使用 Jconsle 与 GC 日志分析程序 JVM 运行状态

最近在学习 JVM,刚好论文的实验代码出现运行过慢的情况,所以想通过 Jconsle 查看代码运行中 JVM 的情况。

Jconsole中对内存为如下结构:


image

其中 Metaspace 是 Java 1.8 之后取消方法区(永久代)后引入的。

Jconsle 连接后,可以看到内存、线程、CPU 等概览。

概览

堆内存

查看程序运行过程中堆内存的使用情况

image

堆内存图上下波动,说明进行了多次 GC ,并且基本没有内存泄漏。从详细信息中也可以看到 新生代用的是 PS Scavenge 垃圾收集器,这是一个并行的多线程的收集器,目标时控制吞吐量。老年代用的是 PS MarkSweep (Serial Old)收集器,是一个单线程,使用标记-整理算法。

从图中可以看出,老年代GC了一次,新生代 GC 了4525次。新生代 GC 频繁应该与我代码中在循环体里面创建矩阵对象有关。

以下分别是新生代 Eden 区,Survivor 区和老年代的内存状态图,也印证了 Minor GC 频繁的现象。但是 GC 所占用的时间与程序整体时间相比并不多,这个算法运行时间在10分钟左右。

Eden

Survivor

Old Gen

GC 原理

image

新生代的GC使用复制算法。在GC前To survivor区保持清空,对象保存在Eden和From survivor区中,GC运行时,Eden中的幸存对象被复制到 To survivor区。针对 From survivor取中的幸存对象,会考虑对象年龄,如果年龄没达到阀值(tenuring threshold),对象会被复制到To survivor区。如果达到阀值对象被复制到老年代。复制阶段完成后,Eden 和From survivor区中只保存死对象,可以被视为全部清空。如果在复制过程中To survivor区被填满了,剩余的对象会被复制到老年代中。最后 From和To会对换。

image

GC 日志

程序运行时加入 -XX:+PrintGCDetails 参数。
列出一部分GC日志如下

[Full GC (Ergonomics) [PSYoungGen: 69883K->0K(657920K)] [ParOldGen: 182607K->93569K(191488K)] 252491K->93569K(849408K), [Metaspace: 8524K->8524K(1056768K)], 0.0221501 secs] [Times: user=0.06 sys=0.00, real=0.02 secs] 

[GC (Allocation Failure) [PSYoungGen: 111648K->32K(131584K)] 212646K->101030K(323072K), 0.0005877 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 131104K->32K(127488K)] 232102K->101030K(318976K), 0.0006413 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 126496K->64K(122880K)] 227494K->101062K(314368K), 0.0006811 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 122432K->32K(119296K)] 223430K->101038K(310784K), 0.0005787 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 118304K->64K(114688K)] 219310K->101070K(306176K), 0.0006089 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 114240K->32K(111616K)] 215246K->101038K(303104K), 0.0007545 secs] [Times: user=0.03 sys=0.00, real=0.00 secs] 

Heap
 PSYoungGen      total 111616K, used 17726K [0x0000000780900000, 0x000000079dd00000, 0x00000007c0000000)
  eden space 110592K, 15% used [0x0000000780900000,0x0000000781a47890,0x0000000787500000)
  from space 1024K, 3% used [0x000000079db00000,0x000000079db08000,0x000000079dc00000)
  to   space 512K, 0% used [0x000000079dc80000,0x000000079dc80000,0x000000079dd00000)
 ParOldGen       total 191488K, used 101006K [0x0000000701a00000, 0x000000070d500000, 0x0000000780900000)
  object space 191488K, 52% used [0x0000000701a00000,0x0000000707ca3818,0x000000070d500000)
 Metaspace       used 8799K, capacity 9006K, committed 9216K, reserved 1056768K
  class space    used 948K, capacity 999K, committed 1024K, reserved 1048576K

(1)GC, Full GC说明了这次垃圾收集的停顿类型,而不是用来区分新生代GC还是老年代GC。如果有"Full",则表示这次GC发生了"Stop-The-World"。

(2)PSYoungGen, ParOldGen,Metaspace 表示GC发生的区域,这里显示的区域名称与使用的GC收集器密切相关,不同收集器对于不同区域所显示的名称可能不同。

(3)接下来"111648K->32K(131584K)"的含义是:GC前该内存区域已使用容量 -> GC后该内存区域已使用容量(该内存区域的总容量)。

(4)"212646K->101030K(323072K)"的含义是:GC前Java堆已使用容量 -> GC后Java堆已使用容量(Java堆总容量) 。

(5)"0.0005877 secs" 表示该内存区域GC所占用的时间,单位是秒。

(6)[Times: user=0.01 sys=0.01, real=0.00 secs]:分别表示用户态消耗CPU时间, 内核态消耗CPU时间,操作从开始到结束所经过的墙钟时间。

(7)Allocation Failure 代表了 GC 的原因,没有足够的空间分配资源。

PS,CPU时间与墙钟时间的区别是:墙钟时间包括各种非运算的等待耗时,例如等待磁盘I/O、等待线程阻塞等;而CPU时间不包括这些耗时。

当系统有多cpu或者多核的话,多线程操作会叠加这些CPU时间,所以有时看到user或sys时间超过real时间是完全正常的。

尝试减少 GC 次数的实践

直接调整堆大小

-Xms1024m -Xmx1024m

发现 Minor GC 在 Eden 300m 左右开始发生,GC 次数明显减少,原因还是内存无法分配。从程序运行结果来看,运行时间并没有改变,所以可以确定程序执行慢,不是 GC 的原因,是代码逻辑的原因。

TIM截图20180810103743
[GC (Allocation Failure) [PSYoungGen: 348672K->498K(347648K)] 587643K->240102K(1047040K), 0.0015896 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 347634K->64K(348160K)] 587238K->240182K(1047552K), 0.0013313 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 

Heap
 PSYoungGen      total 348160K, used 275395K [0x00000000eab00000, 0x0000000100000000, 0x0000000100000000)
  eden space 347136K, 79% used [0x00000000eab00000,0x00000000fb7e0ef0,0x00000000ffe00000)
  from space 1024K, 6% used [0x00000000ffe00000,0x00000000ffe10000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 699392K, used 240118K [0x00000000c0000000, 0x00000000eab00000, 0x00000000eab00000)
  object space 699392K, 34% used [0x00000000c0000000,0x00000000cea7d958,0x00000000eab00000)
 Metaspace       used 12864K, capacity 13342K, committed 13696K, reserved 1060864K
  class space    used 1436K, capacity 1554K, committed 1664K, reserved 1048576K

将循环中不用的矩阵对象置 null 测试

一般 null 对象会被作为垃圾处理,有利于收集器判定垃圾,提高 GC 效率。

TIM截图20180810105805

从结果来看基本没有变化,思考原因,应该是矩阵对象本来就比较大,在 Eden 区存放不下时发生 GC,清楚无用对象。这里将较大对象置 null,对 GC 次数影响不大。

总结

通过 Jconsle 与 GC 日志,简单实践了 JVM 相关参数应用,查看了程序运行时 JVM 内存状态。派出了论文代码运行缓慢关于 GC 方面的原因。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容