(转)JVM GC日志分析及性能优化

重新认知JVM:

  通过前面从Class文件到类装载器,再到运行时数据区的过程。我们画张图展示了JVM的大体物理结构图。

GC优化:

  内存被使用了之后,难免会有不够用或者达到设定值的时候,就需要对内存空间进行垃圾回收。

  GC是由JVM自动完成的,根据JVM系统环境而定,所以时机是不确定的。 当然,我们可以手动进行垃圾回收,比如调用System.gc()方法通知JVM进行一次垃圾回收,但是具体什么时刻运行也无法控制。也就是说System.gc()只是通知要回收,什么时候回收由JVM决定。 但是不建议手动调用该方法,因为消耗的资源比较大。一般以下几种情况会发生垃圾回收

当Eden区或者S区不够用了

老年代空间不够用了

方法区空间不够用了

System.gc()

GC日志文件:

  首先回顾一下各个垃圾收集器对应的代。

ParallelGC Log:

  要想分析日志的信息,得先拿到GC日志文件才行,所以得先配置一下,之前也看过这些参数。然后启动项目

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:gc.log

  到项目根目录下找到 gc.log 文件打开:可以看到默认使用的是ParallelGC

   注意 如果回收的差值中间有出入,说明这部分空间是Old区释放出来的

CMS GC  Log:

  停顿时间优先,参数设置:-XX:+UseConcMarkSweepGC -Xloggc:cms-gc.log 

G1日志:

  停顿时间优先,参数设置:-XX:+UseG1GC -Xloggc:g1-gc.log

理解G1日志格式可以参考:https://blogs.oracle.com/poonam/understanding-g1-gc-logs

-XX:+UseG1GC  # 使用了G1垃圾收集器

# 什么时候发生的GC,相对的时间刻,GC发生的区域young,总共花费的时间,0.00478s,

# It isa stop-the-world activity and all

# the application threads are stopped at a safepoint during this time.2019-12-18T16:06:46.508+0800:0.458: [GC pause (G1 Evacuation Pause) (young),0.0047804 secs]

# 多少个垃圾回收线程,并行的时间

[Parallel Time: 3.0ms, GC Workers:4]

# GC线程开始相对于上面的0.458的时间刻

[GC Worker Start (ms): Min: 458.5, Avg:458.5, Max:458.5, Diff:0.0]

# This gives us the time spent by each worker thread scanning the roots

# (globals, registers, thread stacks and VM data structures).

[Ext Root Scanning (ms): Min: 0.2, Avg:0.4, Max:0.7, Diff:0.5, Sum:1.7]

# Update RS gives us the time each thread spent in updating the Remembered Sets.

[Update RS (ms): Min: 0.0, Avg:0.0, Max:0.0, Diff:0.0, Sum:0.0]

...

常见GC日志文件分析工具:

gceasy:

GC Easy是一款在线的可视化工具,易用、功能强大。官网 :https://gceasy.io 。可以比较不同的垃圾收集器的吞吐量和停顿时间,比如打开cms-gc.log和g1-gc.log


 GCViewer:

  需要下载 gcviewer-1.36-SNAPSHOT.jar ,然后运行这个jar。

G1调优与最佳指南:

调优,是否选用G1垃圾收集器的判断依据,https://docs.oracle.com/javase/8/docs/technotes/guides/vm/G1.html#use_cases

50%以上的堆被存活对象占用

对象分配和晋升的速度变化非常大

垃圾回收时间比较长

  使用G1GC垃圾收集器: -XX:+UseG1GC 。修改配置参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput    Min Pause    Max Pause   Avg Pause    GC count99.16%0.00016s0.0137s0.00559s12

  调整内存大小再获取gc日志分析

-XX:MetaspaceSize=100M-Xms300M-Xmx300M

  比如设置堆内存的大小,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput    Min Pause    Max Pause   Avg Pause    GC count98.89%0.00021s0.01531s0.00538s12

  启动并发GC时堆内存占用百分比: -XX:InitiatingHeapOccupancyPercent=45 G1用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比例。值为 0 则表示“一直执行GC循环)'. 默认值为 45 (例如, 全部的 45% 或者使用了45%).比如设置该百分比参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间

Throughput    Min Pause    Max Pause   Avg Pause    GC count98.11%0.00406s0.00532s0.00469s12

最佳指南:

官网建议 :https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations

不要手动设置新生代和老年代的大小,只要设置整个堆的大小:G1收集器在运行过程中,会自己调整新生代和老年代的大小其实是通过adapt代的大小来调整对象晋升的速度和年龄,从而达到为收集器设置的暂停时间目标如果手动设置了大小就意味着放弃了G1的自动调优不断调优暂停时间目标一般情况下这个值设置到100ms或者200ms都是可以的(不同情况下会不一样),但如果设置成50ms就不太合理。暂停时间设置的太短,就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以对这个参数的调优是一个持续的过程,逐步调整到最佳状态。暂停时间只是一个目标,并不能总是得到满足。

  使用-XX:ConcGCThreads=n来增加标记线程的数量,IHOP(InitiatingHeapOccupancyPercent)如果阀值设置过高,可能会遇到转移失败的风险,比如对象进行转移时空间不足。如果阀值设置过低,就会使标记周期运行过于频繁,并且有可能混合收集期回收不到空间。IHOP值如果设置合理,但是在并发周期时间过长时,可以尝试增加并发线程数,调高ConcGCThreads。

  MixedGC 混合回收调优:mixed GC就是把一部分老年区的region加到Eden和Survivor from的后面,合起来称为collection set, 就是将被回收的集合,下次mixed GC evacuation把他们所有都一并清理。

-XX:InitiatingHeapOccupancyPercent //设置触发标记周期的Java堆占用阈值,默认值为45。-XX:G1MixedGCLiveThresholdPercent //设置在标记周期完成之后混合收集的数量,以维持oldregion(也就是老年代)中,最多有G1MixedGCLiveThresholdPercent的存活对象。默认值为8-XX:G1MixedGCCountTarger  //一个混合收集周期中包含多少次混合收集-XX:G1OldCSetRegionThresholdPercent //一次混合收集中被收集的oldregion数量的上线,默认值是整个堆的10%

适当增加堆内存大小

高并发场景分析:

  如下图,当一个订单服务以每秒3000单的速度请求,然后请求的订单服务的集群数为3。假设每次请求产生的订单的实例在内存中所占大小为1KB,具体的计算可以根据对象头内的内容进行计算,此时订单服务可能还会调用其他的服务,此过程也会产生对象,那么扩大20倍,此时每个节点每秒点单服务会产生20MB的内存占用,假设堆内存为4000MB,那么Young为1333MB. 65秒后这个Young区便会满触发Minor GC。对象晋升,步入老年代,这样的速率会导致老年代的内存很快就满了,就会触发Major GC,Metaspace 区域也会频繁的GC,这样子会触发Full GC。那么这个时候我们可以适当的增加 Young区大小,调整Young区跟Old区的比例。

JVM性能优化指南:

常见问题思考:

内存泄漏与内存溢出的区别?:内存泄漏:对象无法得到及时的回收,持续占用内存空间,从而造成内存空间的浪费。内存溢出:内存泄漏到一定的程度就会导致内存溢出,但是内存溢出也有可能是大对象导致的。

young gc会有stw吗?不管什么 GC,都会有 stop-the-world,只是发生时间的长短。

major gc和full gc的区别?:major gc指的是老年代的gc,而full gc等于young+old+metaspace的gc。

G1与CMS的区别是什么?:CMS 用于老年代的回收,而 G1 用于新生代和老年代的回收。G1 使用了 Region 方式对堆内存进行了划分,且基于标记整理算法实现,整体减少了垃圾碎片的产生。

什么是直接内存?:直接内存是在java堆外的、直接向系统申请的内存空间。通常访问直接内存的速度会优于Java堆。因此出于性能的考虑,读写频繁的场合可能会考虑使用直接内存。

不可达的对象一定要被回收吗?:即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法,或 finalize 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收。

方法区中的无用类回收:方法区主要回收的是无用的类,那么如何判断一个类是无用的类的呢?判定一个常量是否是“废弃常量”比较简单,而要判定一个类是否是“无用的类”的条件则相对苛刻许多。类需要同时满足下面 3 个条件才能算是 “无用的类” :该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。加载该类的 ClassLoader 已经被回收。该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。虚拟机可以对满足上述 3 个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用了就会必然被回收。

不同的引用:JDK1.2以后,Java对引用进行了扩充:强引用、软引用、弱引用和虚引用。

https://www.cnblogs.com/wuzhenzhao/p/12486840.html

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