关于GC

1,198 阅读3分钟

1、触发FGC 的条件

1、老年代可用内存小于新生代全部对象的大小,如果没开启空间担保参数,会直接触发Full GC,所以一般空间担保参数都会打开; 2、老年代可用内存小于历次新生代GC后进入老年代的平均对象大小,此时会提前Full GC; 3、新生代Minor GC后的存活对象大于Survivor,那么就会进入老年代,此时老年代内存不足。 4、老年代自身可以设置一个阈值,有一个JVM参数可以控制,一旦老年代内存使用达到这个阈值,就会触发Full GC,一般建议调节大一些,比如92%

2、parnew+cms的gc,如何保证只做ygc,jvm参数如何配置?

1.设置HandlePromotionFailure,使用空间担保机制,避免直接full gc。 2.修改e区和s区的比例,让s区的空间尽可能的大。 3.修改参数PretenureSizeThreshold ,设置大对象的界限,尽可能的大。 4.使用监控工具,监控每次晋升对象的平均大小,优化代码,尽量降低每次存活对象的平均大小。

设置: MaxTenuringThreshold 大于 15 无效,

事实上MaxTenuringThreshold这个参数最大就是15,这是因为一个对象的对象头里有4bit记录的是GC分代年龄,最大就是1111,也就是15

3、对象什么时候进入老年代

1、一个对象在年轻代里躲过15次垃圾回收,年龄太大了,寿终正寝,进入老年代 2、动态年龄判定规则,如果一旦发现某次新生代GC过后,存活对象超过了Survivor的50% 3、对象太大了,超过了一定的阈值,直接进入老年代,不走年轻代 4、一次Young GC过后存活对象太多了,导致Survivor区域放不下了,这批对象会进入老年代

4、正常系统多久一次YGC / FGC

正常有一定流量的系统如果还有一定的并发量,大概几分钟 ~ 几十分钟一次 YGC,一次 几毫秒到 几十毫秒,

几十分钟 ~ 几个小时 ~ 几天一次 FGC 一次大概是 几百毫秒

如果频繁 YGC 比较一分钟好几次,每次上百 毫秒

频繁 FGC 几分钟就一次 FGC,一次几秒钟 这都是不正常的,就需要优化了。

5、系统上线时要压测哪些参数

Eden区的对象增长速率多块? Young GC频率多高? 一次Young GC多长耗时? Young GC过后多少对象存活? 老年代的对象增长速率多高? Full GC频率多高?一次Full GC耗时?

6、哪些情况可能是发送了FGC?

1、机器的 CPU 负载很高 2、频繁的FGC 报警 3、系统无法处理请求或者接口响应超时

7、频繁FGC 的几种常见原因

1、系统承载高并发请求,或者处理数据量过大,导致Young GC很频繁,而且每次Young GC过后存活对象太多,内存分配不合理,Survivor区域过小,导致对象频繁进入老年代,频繁触发Full GC。 2、系统一次性加载过多数据进内存,搞出来很多大对象,导致频繁有大对象进入老年代,必然频繁触发Full GC 3、系统发生了内存泄漏,莫名其妙创建大量的对象,始终无法回收,一直占用在老年代里,必然频繁触发Full GC 4、Metaspace(永久代)因为加载类过多触发Full GC 5、误调用System.gc()触发Full GC