本人学习过程中所整理的代码,
以下大部分内容摘自《深入理解Java虚拟机》
现在几乎没有虚拟机实现采用抢先式中断来暂停线程从而响应GC事件
遍历老年代,然后标记所有存活的对象,它会根据上个阶段找到的GC Roots遍历查找,它会与用户的应用程序并发运行,并不是老年代所有的存活对象都会被标记,因为在标记期间用户的程序可能会改变一些引用
与应用的线程并发运行,一些对象的引用可能会发生变化,但是这种情况发生时,JVM会将包含这个对象的区域(Card)标记为Dirty,这也就是Card Marking
在pre-clean阶段,那些能够从Dirty对象到达的对象也会被标记,这个标记做完后,dirty card标记就会被清除了
并发阶段,这个阶段是为了尽量承担STW中最终标记阶段的工作。这个阶段持续时间依赖于很多的因素,由于是在重复做很多相同的工作,直接满足一些条件(如重复迭代的次数、完成的工作量或者时钟时间等)
第二个STW阶段,这个阶段的目标是标记老年代所有的存活对象,由于之前的阶段是并发执行的,GC线程可能跟不上应用程序的变化,为了完成标记老年代所有存活对象的目标,STW就非常有必要了
通常CMS的Final Remarj阶段会在年轻代尽可能干净的时候运行,目的是为了减少连续STW发生的可能性(年轻代存活对象过多也会导致老年代涉及的存活对象过多),这个阶段会比前面几个阶段更复杂一些
至此为止,标记阶段已经完成,开始通过清除算法清除
与用户的应用程序并发运行,这个阶段是为了清除那些不再使用的对象,回收它们的占用空间为将来使用
并发执行,它会重设CMS内部的数据结构,为下次的GC做准备
总结:CMS通过将大量工作分散到并发处理阶段来减少STW时间,在这块做得非常优秀,但CMS收集器无法处理浮动垃圾,并且会导致空间碎片,导致无法分配大对象;对于堆比较大的应用,GC的时间难以预估
测试用例:
VM Option:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC
public class MyTest5 {
public static void main(String[] args) throws InterruptedException {
int size = 1024 * 1024;
byte[] myAlloc1 = new byte[4 * size];
System.out.println("111111");
byte[] myAlloc2 = new byte[4 * size];
System.out.println("222222");
byte[] myAlloc3 = new byte[4 * size];
System.out.println("333333");
Thread.sleep(1000);
byte[] myAlloc4 = new byte[2 * size];
System.out.println("444444");
}
}
打印日志:
111111
[GC (Allocation Failure) [ParNew: 6322K->685K(9216K), 0.0023811 secs] 6322K->4783K(19456K), 0.0024408 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
222222
[GC (Allocation Failure) [ParNew: 5020K->153K(9216K), 0.0036918 secs] 9119K->9002K(19456K), 0.0037384 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (CMS Initial Mark) [1 CMS-initial-mark: 8848K(10240K)] 13098K(19456K), 0.0002609 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-mark-start]
333333
[CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-abortable-preclean-start]
[CMS-concurrent-abortable-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (CMS Final Remark) [YG occupancy: 4405 K (9216 K)][Rescan (parallel) , 0.0001423 secs][weak refs processing, 0.0000232 secs][class unloading, 0.0004092 secs][scrub symbol table, 0.0007216 secs][scrub string table, 0.0001729 secs][1 CMS-remark: 8848K(10240K)] 13253K(19456K), 0.0015660 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
444444
Heap
par new generation total 9216K, used 7798K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 8192K, 93% used [0x00000000fec00000, 0x00000000ff3771a8, 0x00000000ff400000)
from space 1024K, 15% used [0x00000000ff400000, 0x00000000ff426710, 0x00000000ff500000)
to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
concurrent mark-sweep generation total 10240K, used 8847K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
Metaspace used 3945K, capacity 4568K, committed 48K, reserved 1056768K
class space used 434K, capacity 460K, committed 512K, reserved 1048576K
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ovod.cn 版权所有 湘ICP备2023023988号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务