本文主要研究一下GarbageCollectionNotificationInfo

CompositeData
java.management/javax/management/openmbean/CompositeData.java

public interface CompositeData {

public CompositeType getCompositeType();

public Object get(String key) ;

public Object[] getAll(String[] keys) ;

public boolean containsKey(String key) ;

public boolean containsValue(Object value) ;

public Collection<?> values() ;

public boolean equals(Object obj) ;

public int hashCode() ;

public String toString() ;

}
CompositeData接口定义了getCompositeType、get、getAll、containsKey、containsValue、values、equals、hashCode、toString方法
CompositeDataView
java.management/javax/management/openmbean/CompositeDataView.java

public interface CompositeDataView {

public CompositeData toCompositeData(CompositeType ct);
}
CompositeDataView接口定义了toCompositeData方法,用于将数据转换为CompositeData
GcInfo
jdk.management/com/sun/management/GcInfo.java

public class GcInfo implements CompositeData, CompositeDataView {
private final long index;
private final long startTime;
private final long endTime;
private final Map<String, MemoryUsage> usageBeforeGc;
private final Map<String, MemoryUsage> usageAfterGc;
private final Object[] extAttributes;
private final CompositeData cdata;
private final GcInfoBuilder builder;

private GcInfo(GcInfoBuilder builder,
long index, long startTime, long endTime,
MemoryUsage[] muBeforeGc,
MemoryUsage[] muAfterGc,
Object[] extAttributes) {
this.builder = builder;
this.index = index;
this.startTime = startTime;
this.endTime = endTime;
String[] poolNames = builder.getPoolNames();
this.usageBeforeGc = new HashMap<String, MemoryUsage>(poolNames.length);
this.usageAfterGc = new HashMap<String, MemoryUsage>(poolNames.length);
for (int i = 0; i < poolNames.length; i++) {
this.usageBeforeGc.put(poolNames[i], muBeforeGc[i]);
this.usageAfterGc.put(poolNames[i], muAfterGc[i]);
}
this.extAttributes = extAttributes;
this.cdata = new GcInfoCompositeData(this, builder, extAttributes);
}

private GcInfo(CompositeData cd) {
GcInfoCompositeData.validateCompositeData(cd);

this.index = GcInfoCompositeData.getId(cd);
this.startTime = GcInfoCompositeData.getStartTime(cd);
this.endTime = GcInfoCompositeData.getEndTime(cd);
this.usageBeforeGc = GcInfoCompositeData.getMemoryUsageBeforeGc(cd);
this.usageAfterGc = GcInfoCompositeData.getMemoryUsageAfterGc(cd);
this.extAttributes = null;
this.builder = null;
this.cdata = cd;
}

public long getId() {
return index;
}

public long getStartTime() {
return startTime;
}

public long getEndTime() {
return endTime;
}

public long getDuration() {
return endTime - startTime;
}

public Map<String, MemoryUsage> getMemoryUsageBeforeGc() {
return Collections.unmodifiableMap(usageBeforeGc);
}

public Map<String, MemoryUsage> getMemoryUsageAfterGc() {
return Collections.unmodifiableMap(usageAfterGc);
}

public static GcInfo from(CompositeData cd) {
if (cd == null) {
return null;
}

if (cd instanceof GcInfoCompositeData) {
return ((GcInfoCompositeData) cd).getGcInfo();
} else {
return new GcInfo(cd);
}

}

// Implementation of the CompositeData interface
public boolean containsKey(String key) {
return cdata.containsKey(key);
}

public boolean containsValue(Object value) {
return cdata.containsValue(value);
}

public boolean equals(Object obj) {
return cdata.equals(obj);
}

public Object get(String key) {
return cdata.get(key);
}

public Object[] getAll(String[] keys) {
return cdata.getAll(keys);
}

public CompositeType getCompositeType() {
return cdata.getCompositeType();
}

public int hashCode() {
return cdata.hashCode();
}

public String toString() {
return cdata.toString();
}

public Collection<?> values() {
return cdata.values();
}

public CompositeData toCompositeData(CompositeType ct) {
return cdata;
}
}
GcInfo实现了CompositeData及CompositeDataView接口,它主要有index、startTime、endTime、usageBeforeGc、usageAfterGc、extAttributes、cdata这几个属性
GarbageCollectionNotificationInfo
jdk.management/com/sun/management/GarbageCollectionNotificationInfo.java

public class GarbageCollectionNotificationInfo implements CompositeDataView {

private final String gcName;
private final String gcAction;
private final String gcCause;
private final GcInfo gcInfo;
private final CompositeData cdata;

public static final String GARBAGE_COLLECTION_NOTIFICATION =
"com.sun.management.gc.notification";

public GarbageCollectionNotificationInfo(String gcName,
String gcAction,
String gcCause,
GcInfo gcInfo) {
if (gcName == null) {
throw new NullPointerException("Null gcName");
}
if (gcAction == null) {
throw new NullPointerException("Null gcAction");
}
if (gcCause == null) {
throw new NullPointerException("Null gcCause");
}
this.gcName = gcName;
this.gcAction = gcAction;
this.gcCause = gcCause;
this.gcInfo = gcInfo;
this.cdata = new GarbageCollectionNotifInfoCompositeData(this);
}

GarbageCollectionNotificationInfo(CompositeData cd) {
GarbageCollectionNotifInfoCompositeData.validateCompositeData(cd);

this.gcName = GarbageCollectionNotifInfoCompositeData.getGcName(cd);
this.gcAction = GarbageCollectionNotifInfoCompositeData.getGcAction(cd);
this.gcCause = GarbageCollectionNotifInfoCompositeData.getGcCause(cd);
this.gcInfo = GarbageCollectionNotifInfoCompositeData.getGcInfo(cd);
this.cdata = cd;
}

public String getGcName() {
return gcName;
}

public String getGcAction() {
return gcAction;
}

public String getGcCause() {
return gcCause;
}

public GcInfo getGcInfo() {
return gcInfo;
}

public static GarbageCollectionNotificationInfo from(CompositeData cd) {
if (cd == null) {
return null;
}

if (cd instanceof GarbageCollectionNotifInfoCompositeData) {
return ((GarbageCollectionNotifInfoCompositeData) cd).getGarbageCollectionNotifInfo();
} else {
return new GarbageCollectionNotificationInfo(cd);
}
}

public CompositeData toCompositeData(CompositeType ct) {
return cdata;
}

}
GarbageCollectionNotificationInfo实现了CompositeDataView接口的toCompositeData方法,它主要有gcName、gcAction、gcCause、gcInfo、cdata这几个属性,toCompositeData返回的是cdata
实例
G1
G1 Young Generation
{
"gcAction": "end of minor GC",
"gcCause": "G1 Evacuation Pause",
"gcInfo": {
"compositeType": {
"className": "javax.management.openmbean.CompositeData",
"description": "CompositeType for GC www.huarenyl.cn info for G1 Young Generation",
"typeName": "sun.management.G1 Young Generation.GcInfoCompositeType"
},
"duration": 29,
"endTime": 18593,
"id": 38,
"memoryUsageAfterGc": {
"CodeHeap 'profiled nmethods'": {
"committed": 8847360,
"init": 2555904,
"max": 122912768,
"used": 8816000
},
"G1 Old Gen": {
"committed": 88080384,
"init": 17825792,
"max": 524288000,
"used": 62842880
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 1793408
},
"G1 Survivor Space": {
"committed": 2097152,
"init": 0,
"max": -1,
"used": 2097152
},
"Compressed Class Space": {
"committed": 6160384,
"init": 0,
"max": 1073741824,
"used": 5670976
},
"Metaspace": {
"committed": 49676288,
"init": 0,
"max": -1,
"used": 48404152
},
"G1 Eden Space": {
"committed": 13631488,
"init": 15728640,
"max": -1,
"used": 0
},
"CodeHeap 'non-nmethods'www.myptvip8.com": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1199360
}
},
"memoryUsageBeforeGc": {
"CodeHeap 'profiled nmethods'": {
"committed": 8847360,
"init": 2555904,
"max": 122912768,
"used": 8816000
},
"G1 Old Gen": {
"committed": 89128960,
"init": 17825792,
"max": 524288000,
"used": 59823984
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 1793408
},
"G1 Survivor Space": {
"committed": 1048576,
"init": 0,
"max": -1,
"used": 1048576
},
"Compressed Class Space": {
"committed": 6160384,
"init": 0,
"max": 1073741824,
"used": 5670976
},
"Metaspace": {
"committed": 49676288,
"init": 0,
"max": -1,
"used": 48404152
},
"G1 Eden Space": {
"committed": 13631488,
"init": 15728640,
"max": -1,
"used": 12582912
},
"CodeHeap 'non-nmethods'www.feifanyule.cn": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1199360
}
},
"startTime": 18564
},
"gcName": "G1 Young Generation"
}
G1 Old Generation
{
"gcAction": "end of major GC",
"gcCause": "G1 Evacuation Pause",
"gcInfo": {
"compositeType": {
"className": "javax.management.openmbean.CompositeData",
"description": "CompositeType for GC info for G1 Old Generation",
"typeName": "sun.management.G1 Old Generation.GcInfoCompositeType"
},
"duration": 127,
"endTime": 14107,
"id": 2,
"memoryUsageAfterGc": {
"CodeHeap 'profiled nmethods'": {
"committed": 9043968,
"init": 2555904,
"max": 122912768,
"used": 9008768
},
"G1 Old Gen": {
"committed": 50331648,
"init": 15728640,
"max": 67108864,
"used": 50126800
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 1814144
},
"G1 Survivor Space"www.honghgjpt.com: {
"committed": 0,
"init": 0,
"max": -1,
"used": 0
},
"Compressed Class Space": {
"committed": 6160384,
"init": 0,
"max": 1073741824,
"used": 5631528
},
"Metaspace": {
"committed": 49676288,
"init": 0,
"max": -1,
"used": 48270608
},
"G1 Eden Space": {
"committed": 16777216,
"init": 17825792,
"max": -1,
"used": 0
},
"CodeHeap 'non-nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1197696
}
},
"memoryUsageBeforeGc"www.365soke.com: {
"CodeHeap 'profiled nmethods'": {
"committed": 9043968,
"init": 2555904,
"max": 122912768,
"used": 9008768
},
"G1 Old Gen": {
"committed": 65011712,
"init": 15728640,
"max": 67108864,
"used": 64820264
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 1814144
},
"G1 Survivor Space": {
"committed": 1048576,
"init": 0,
"max": -1,
"used": 1048576
},
"Compressed Class Space": {
"committed": 6160384,
"init": 0,
"max": 1073741824,
"used": 5664624
},
"Metaspace": {
"committed": 49676288,
"init": 0,
"max": -1,
"used": 48375680
},
"G1 Eden Space": {
"committed": 1048576,
"init": 17825792,
"max": -1,
"used": 0
},
"CodeHeap 'non-nmethods'www.yunshengpt.com": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1197696
}
},
"startTime": 13980
},
"gcName": "G1 Old Generation"
}
ZGC
ZGC Warmup
{
"gcAction": "end of major GC",
"gcCause": "Warmup",
"gcInfo": {
"compositeType": {
"className": "javax.management.openmbean.CompositeData",
"description": "CompositeType for GC info for ZGC",
"typeName": "sun.management.ZGC.GcInfoCompositeType"
},
"duration": 6562,
"endTime": 28676,
"id": 2,
"memoryUsageAfterGc": {
"ZHeap": {
"committed": 2145386496,
"init": 2147483648,
"max": 2147483648,
"used": 656408576
},
"CodeHeap 'profiled nmethods'": {
"committed": 9830400,
"init": 2555904,
"max": 122912768,
"used": 9767424
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 2076288
},
"Metaspace": {
"committed": 49020928,
"init": 0,
"max": -1,
"used": 47278192
},
"CodeHeap 'non-nmethods'www.078881.cn/": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1190528
}
},
"memoryUsageBeforeGc": {
"ZHeap": {
"committed": 2145386496,
"init": 2147483648,
"max": 2147483648,
"used": 444596224
},
"CodeHeap 'profiled nmethods'": {
"committed": 9568256,
"init": 2555904,
"max": 122912768,
"used": 9546880
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 2051968
},
"Metaspace": {
"committed": 49020928,
"init": 0,
"max": -1,
"used": 47895808
},
"CodeHeap 'non-nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1184768
}
},
"startTime": 22114
},
"gcName": "ZGC"
}
ZGC Allocation Rate
{
"gcAction": "end of major GC",
"gcCause": "Allocation Rate",
"gcInfo": {
"compositeType": {
"className": "javax.management.openmbean.CompositeData",
"description": "CompositeType for GC info for ZGC",
"typeName": "sun.management.ZGC.GcInfoCompositeType"
},
"duration": 1028,
"endTime": 288728,
"id": 3,
"memoryUsageAfterGc": {
"ZHeap": {
"committed": 2145386496,
"init": 2147483648,
"max": 2147483648,
"used": 278921216
},
"CodeHeap 'profiled nmethods'": {
"committed": 11206656,
"init": 2555904,
"max": 122912768,
"used": 11141248
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 2198656
},
"Metaspace": {
"committed": 49283072,
"init": 0,
"max": -1,
"used": 48287392
},
"CodeHeap 'non-nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1184768
}
},
"memoryUsageBeforeGc": {
"ZHeap": {
"committed": 2145386496,
"init": 2147483648,
"max": 2147483648,
"used": 236978176
},
"CodeHeap 'profiled nmethods'": {
"committed": 11010048,
"init": 2555904,
"max": 122912768,
"used": 11005568
},
"CodeHeap 'non-profiled nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 122916864,
"used": 2197632
},
"Metaspace": {
"committed": 48758784,
"init": 0,
"max": -1,
"used": 47908112
},
"CodeHeap 'non-nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 5828608,
"used": 1184128
}
},
"startTime": 287700
},
"gcName": "ZGC"
}
Shenandoah
Shenandoah Cycles
{
"gcAction": "end of GC cycle",
"gcCause": "No GC",
"gcInfo": {
"compositeType": {
"className": "javax.management.openmbean.CompositeData",
"description": "CompositeType for GC info for Shenandoah Cycles",
"typeName": "sun.management.Shenandoah Cycles.GcInfoCompositeType"
},
"duration": 18,
"endTime": 1201551,
"id": 5,
"memoryUsageAfterGc": {
"CodeHeap 'non-profiled nmethods'": {
"committed": 9371648,
"init": 2555904,
"max": 244105216,
"used": 9310592
},
"Shenandoah": {
"committed": 54525952,
"init": 4294967296,
"max": 4294967296,
"used": 34113640
},
"Compressed Class Space": {
"committed": 5373952,
"init": 0,
"max": 1073741824,
"used": 4724464
},
"Metaspace": {
"committed": 37355520,
"init": 0,
"max": -1,
"used": 35581640
},
"CodeHeap 'non-nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 7553024,
"used": 1209216
}
},
"memoryUsageBeforeGc": {
"CodeHeap 'non-profiled nmethods'": {
"committed": 9306112,
"init": 2555904,
"max": 244105216,
"used": 9300096
},
"Shenandoah": {
"committed": 54525952,
"init": 4294967296,
"max": 4294967296,
"used": 42502592
},
"Compressed Class Space": {
"committed": 5373952,
"init": 0,
"max": 1073741824,
"used": 4724464
},
"Metaspace": {
"committed": 37355520,
"init": 0,
"max": -1,
"used": 35581640
},
"CodeHeap 'non-nmethods'": {
"committed": 2555904,
"init": 2555904,
"max": 7553024,
"used": 1209216
}
},
"startTime": 1201533
},
"gcName": "Shenandoah Cycles"
}
Shenandoah Pauses
{
"gcAction": "end of GC pause",
"gcCause": "No GC",
"gcInfo": {
"compositeType": {
"className": "javax.management.openmbean.CompositeData",
"description": "CompositeType for GC info for Shenandoah Pauses",
"typeName": "sun.management.Shenandoah Pauses.GcInfoCompositeType"
},
"duration": 1,
"endTime": 1201551,
"id": 20,
"memoryUsageAfterGc": {
"CodeHeap 'non-profiled nmethods'": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"Shenandoah": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"Compressed Class Space": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"Metaspace": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"CodeHeap 'non-nmethods'": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
}
},
"memoryUsageBeforeGc": {
"CodeHeap 'non-profiled nmethods'": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"Shenandoah": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"Compressed Class Space": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"Metaspace": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
},
"CodeHeap 'non-nmethods'": {
"committed": 0,
"init": 0,
"max": 0,
"used": 0
}
},
"startTime": 1201550
},
"gcName": "Shenandoah Pauses"
}
小结
GarbageCollectorMXBean在完成一个次垃圾收集的action的时候会发射一个A garbage collection notification,它返回的是GarbageCollectionNotificationInfo
GarbageCollectionNotificationInfo实现了CompositeDataView接口的toCompositeData方法,它主要有gcName、gcAction、gcCause、gcInfo、cdata这几个属性,toCompositeData返回的是cdata;GcInfo实现了CompositeData及CompositeDataView接口,它主要有index、startTime、endTime、usageBeforeGc、usageAfterGc、extAttributes、cdata这几个属性
可以发现无论是使用G1 GC、ZGC还是Shenandoah GC,都能从对应的GarbageCollectionNotificationInfo获取相关信息,只是不同的垃圾收集器除了gcName不一样外,它们的usageBeforeGc及usageAfterGc(Map<String, MemoryUsage>)中的key也不尽相同
doc
GarbageCollectionNotificationInfo

聊聊GarbageCollectionNotificationInfo的更多相关文章

  1. 聊聊Unity项目管理的那些事:Git-flow和Unity

    0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...

  2. Mono为何能跨平台?聊聊CIL(MSIL)

    前言: 其实小匹夫在U3D的开发中一直对U3D的跨平台能力很好奇.到底是什么原理使得U3D可以跨平台呢?后来发现了Mono的作用,并进一步了解到了CIL的存在.所以,作为一个对Unity3D跨平台能力 ...

  3. fir.im Weekly - 聊聊 Google 开发者大会

    中国互联网的三大错觉:索尼倒闭,诺基亚崛起,谷歌重返中国.12月8日,2016 Google 开发者大会正式发布了Google Developers 中国网站 ,包含了Android Develope ...

  4. 聊聊asp.net中Web Api的使用

    扯淡 随着app应用的崛起,后端服务开发的也越来越多,除了很多优秀的nodejs框架之外,微软当然也会在这个方面提供更便捷的开发方式.这是微软一贯的作风,如果从开发的便捷性来说的话微软是当之无愧的老大 ...

  5. 没有神话,聊聊decimal的“障眼法”

    0x00 前言 在上一篇文章<妥协与取舍,解构C#中的小数运算>的留言区域有很多朋友都不约而同的说道了C#中的decimal类型.事实上之前的那篇文章的立意主要在于聊聊使用二进制的计算机是 ...

  6. 聊聊 C 语言中的 sizeof 运算

    聊聊 sizeof 运算 在这两次的课上,同学们已经学到了数组了.下面几节课,应该就会学习到指针.这个速度的确是很快的. 对于同学们来说,暂时应该也有些概念理解起来可能会比较的吃力. 先说一个概念叫内 ...

  7. 聊聊 Apache 开源协议

    摘要 用一句话概括 Apache License 就是,你可以用这代码,但是如果开源你必须保留我写的声明:你可以改我的代码,但是如果开源你必须写清楚你改了哪些:你可以加新的协议要求,但不能与我所 公布 ...

  8. 【原】聊聊js代码异常监控

    在平时的工作,js报错是比较常见的一个情景,尤其是有一些错误可能我们在本地测试的时候测试不出来,当发布到线上之后才可以发现,如果抢救及时,那还好,假如很晚才发 现,那就可能造成很大的损失了.如果我们前 ...

  9. Replication的犄角旮旯(三)--聊聊@bitmap

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

随机推荐

  1. group by用法

    select * from Table group by id,一定不能是*,而是某一个列或者某个列的聚合函数. 参考:http://www.cnblogs.com/jingfengling/p/59 ...

  2. p151开映射札记

    1. 如何理解这句话? 2.连续有什么用? 3.为什么区间包含,经过算子T还是包含? 谢谢 谢谢学长 我懂了  1.2.     3有点儿模糊 1.连续等价于开集原像是开集,而可逆算子的逆的原像就是的 ...

  3. Python_内置函数之zip

    zip函数用于将可迭代的对象作为参数,将对象中的元素打包成一个个元祖,然后返回这些元祖组成的列表.如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同. l1 = [1, 2, 3] l2 ...

  4. 福州大学软件工程1816 | W班 第10次作业[个人作业——软件产品案例分析]

    作业链接 个人作业--软件产品案例分析 评分细则 本次个人项目分数由两部分组成(课堂得分(老师/助教占比60%,学生占比40%)满分40分+博客分满分60分) 课堂得分和博客得分表 评分统计图 千帆竞 ...

  5. snappy

    Snappy 是一个 C++ 的用来压缩和解压缩的开发包.其目标不是最大限度压缩或者兼容其他压缩格式,而是旨在提供高速压缩速度和合理的压缩率.Snappy 比 zlib 更快,但文件相对要大 % 到 ...

  6. asp.net mvc或者其他程序无法打开excel——解决方案,C#处理Excel文件

    问题描述:今天处理Excel时遇到一个问题,本地使用Microsoft.Jet.OLEDB.4.0处理,正常完成了需求, 上传到服务器后发生了异常,通过排查发现问题出现在对Excel文件的读取上,然后 ...

  7. Mybatis 配置resultMap一对多关联映射

    resultMap配置: 引用: PO类: 接口: 测试: public class UserMapperTest { private SqlSessionFactory sqlSessionFact ...

  8. 前K个高频元素

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...

  9. VSCode 汉化

    https://jingyan.baidu.com/article/7e44095377c9d12fc1e2ef5b.html

  10. TextView不用ScrollViewe也可以滚动的方法

    转自:http://www.jb51.net/article/43377.htm android TextView不用ScrollViewe也可以滚动的方法. TextView textview = ...