ParNew和CMS 在G1出之前是一款很火的JVM垃圾收集器
他们都优势在于,更注重吞吐量,多线程的垃圾收集器
多线程的垃圾收集器的优点
多线程的垃圾收集器的优点:在垃圾回收的时候,不会暂停用户线程,而去进行JVM的垃圾回收,这样对用户体验会好很多,用户使用程序,响应时间超过10ms就会觉得程序的反应慢,影响用户体验
线上如何指定ParNew垃圾收集器
-XX:+UseParNewGC
ParNew垃圾收集器的默认线程数量
perNew垃圾收集器的默认线程数量等于,CPU核心线程数量,一般不进行调整,如果要调整的话,使用参数-XX:ParallelGCThreads 可以设置线程数量
JAVA服务器模式和客户端模式有啥区别吗
JAVA服务器模式适用于Linux服务器,原因是因为Linux服务器一般是多核CPU可以高效利用,
客户端模式更适合在Windos上,因为Windos一般是单核,开启多线程比较影响效率
如果是客户端那么在 java -jar 后使用 -client
如果是服务器端的话在java -jar 后使用 -server
一个ParNewGC,一个CMSGC如何保证只做 YongGC
1.先估算,每次进入老年代的内存大小,也可以通过工具查看
2.通过拿到每次进入老年代内存大小的平均值可以,设置好Survivor区域的大小,大于每次进入老年代的内存大小,这样就可以让每次YongGC都在eden和Survivor区域
CMS的基本原理
cms是老年代收集器,他采用的是标记清理算法,标记出哪些对象是垃圾对象,再把这些对象清理掉,这就是标记-清理算法
缺点:这种方法会造成,很多的内存碎片
如果先stop the world 在进行垃圾回收
回造成系统卡死时间很长,很多相应无法处理, 所以CMS收集器尽量采用垃圾收集是一个线程,系统工作是一个线程
CMS如何一边工作一边进行垃圾回收
1.初始化标记(标记GC ROOT对象)
2.并发标记(多线程)(标记GC ROOT的对象引用,这个比较耗时)
3.重新标记(标记这段时间生成的对象)
4.并发清理(多线程)
其中要注意,并发标记和并发清理,因为老年代有大量的对象,所以并发标记追踪对象的时候比较消耗CPU
CMS 默认垃圾收回线程数量
默认垃圾回收线程数量 = (CPU核数 + 3) /4
Concurrent MODE FAILURE
如果CMS发生GC的过程中,会有一部分对象,随着系统运行进入老年代,如果对象过大,进入老年代的对象大小,大于老年代剩余内存大小,那么就会发生Concurrent MODE FAILURE ,发生之后就会将老年代收集器变为Serial old 直接将系统stop the world,并且进行长时间的GC ROOT追踪,标记出全部垃圾,不允许产生新对象,在一次性的把垃圾回收掉,完事了在恢复线程
CMS配置解析
-XX:CMSInitiatingOccupancyFaction 参数可以用来老年代占用多少比例的时候触发CMS回收,(JDK1.6的时候默认是92%)
如果内存碎片太多,会导致新生成的对象没地方放,从而导致频繁的Full GC
-XX:UseCMSCompactAtFullCollection 默认是打开的,就是在FullGC后,会stop the world,整理内存碎片
-XX:CMSFullGCsBeforeCompaction 它的意思是执行多少次FullGC之后,在执行一次整理磁盘碎片,默认是0
什么原因老年代的GC比年轻代GC慢
1.Yong GC只需要看哪些对象是符合进入老年的的标准,直接拿过来就行了
2.老年代的对象一般比年轻代要多一些,而且在CMS发生并发标记的时候,还回去追踪GCROOT看哪些GCROOT是需要标记发生回收的,
3.在并发清理过程中,如果老年代的内存大小不足以发生GC,那么会自动将垃圾收集器转换为Serial old 并且一次性收集完了,在释放线程