jvm相关总结
jvm常用参数
https://mp.weixin.qq.com/s?__biz=MzIwMzY1OTU1NQ==&mid=2247484458&idx=1&sn=09ab6cd3b4187df5bc6e693df57778d5&chksm=96cd4466a1bacd70262a232cf1ae091b528912630a4cb8686c33259b5ca9289e1afc7f334b03&mpshare=1&scene=1&srcid=0818yNvC8sScLesR7jjUdD2X&key=aabb2ccd6a6552351166d5ae3fae009e9ce42be9ad0443233aeef7716871ffa9e9ba6de8ec069a4426ff522833b46ed9fe262772735d065a62d5de188237e8e4172f8e848c350c13c3d4e5d56be9fe7e&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=5aXt5uXOGcgIC7KGUdIaSeIlAcbxVAg2lZI0X5mZh1cMsn46Qh5h0z4PnhyEs5Di
GC主要有YoungGC,OldGC,FullGC(还有G1中独有的Mixed GC,收集整个young区以及部分Old区,提及的概率相对少很多,本篇文章不打算讲解)
截止Java发展到现在JDK9为止,只单独回收Old区的只有CMS GC
对于ParallelOldGC即默认GC在Old满了以后触发的FullGC是没有问题的,jstat命令查看输出结果FGC
的值也会相应的+1,即发生了一次FGC。FGC误解主要来自最常用的ParNew+CMS组合,很多人误解FullGC可能是受到jstat
命令结果的影响,因为发生CMS GC时,FGC也会增大(但是会+2,这是因为CMS GC的初始化标记和重新标记都会完全的STW,从而FGC的值会+2)。但是,事实上这并没有发生FullGC。jstat命令结果中的FGC并不表示就一定发生了FullGC,很有可能只是发生了CMS GC而已。事实上,FullGC的触发条件非常苛刻,判断是否发生了FullGC最好的方法是通过GC日志,日志中如果有"full gc"的字样,就表示一定发生了Full GC。所以强烈建议生产环境开启GC日志,它的价值远大于它对性能的影响(不用权衡这个影响有多大,开启就对了)。
G1或者ParNew+CMS组合前提下,如果真的发生FullGC,则是单线程完全STW的回收方式(SerialGC)退化为单线程,可以想象性能有多差,如果是es,hbase等需要几十个G的堆,那更是灾难。
注意:Paralled Scavenge是否是并行/并发的未知
- 对象优先在Eden分配,当Eden区没有足够空间进行分配时,虚拟机将发起一次Young GC
- 大对象直接进入老年代,避免对象在Eden及两个Survivor直接发生大内存复制
- 长期存活的对象将进入老年代。一般情况下接受过15次Minor GC后晋升老年代 XX:MaxTenuringThreshold可设置
- 当进行Young GC之前,JVM需要预估:老年代是否能够容纳Young GC后新生代晋升到老年代的存活对象,以确定是否需要提前触发GC回收老年代空间,基于空间分配担保策略来计算,continueSize:老年代最大可用连续空间
-
新生代对象的年龄可能没达到阈值(MaxTenuringThreshold参数指定)就晋升老年代,如果Young GC之后,新生代存活对象达到相同年龄所有对象大小的总和大于任一Survivor空间(S0 或 S1总空间)的一半,此时S0或者S1区即将容纳不了存活的新生代对象,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄 动态年龄判定 ------- 另外,如果Young GC后S0或S1区不足以容纳:未达到晋升老年代条件的新生代存活对象,会导致这些存活对象直接进入老年代,需要尽量避免,如下图:
https://segmentfault.com/a/1190000020625913?utm_source=tag-newest
-==============================================-