并行GC(ParNew)
因为Serial 和 ParNew都不推荐使用了,因此现在新生代默认使用的是Parallel Scavenge,也就是新生代和老年代都是使用并行
ParNew(并行)收集器
一句话:使用多线程进行垃圾回收,在垃圾收集时,会Stop-the-World暂停其他所有的工作线程直到它收集结束。
ParNew收集器其实就是Serial收集器新生代的并行多线程版本,最常见的应用场景是配合老年代的CMS GC工作,其余的行为和Serial收集器完全一样,ParNew垃圾收集器在垃圾收集过程中同样也要暂停所有其他的工作线程。它是很多java虚拟机运行在Server模式下新生代的默认垃圾收集器。
常用对应JVM参数:-XX:+UseParNewGC启用ParNew收集器,只影响新生代的收集,不影响老年代
开启上述参数后,会使用: ParNew(Young区用)+ Serial Old的收集器组合,新生代使用复制算法,老年代采用标记-整理算法
但是,ParNew+Tenured这样的搭配,java8已经不再被推荐
Java HotSpot™64-Bit Server VM warning:
Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
备注
-XX:ParallelGCThreads限制线程数量,默认开启和CPU数目相同的线程数
-Xms10m -Xmx10m -X×:+PrintGCDetails -Xx:+UseParNewGc
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC (ParNew+Tenured)
-XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC *******GCDemo hello [GC (Allocation Failure) [ParNew: 2736K->320K(3072K), 0.0007857 secs] 2736K->920K(9920K), 0.0008434 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 2791K->296K(3072K), 0.0006374 secs] 3392K->1507K(9920K), 0.0006622 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 2923K->8K(3072K), 0.0007958 secs] 4134K->2922K(9920K), 0.0008126 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 1532K->4K(3072K), 0.0006431 secs] 4446K->4390K(9920K), 0.0006710 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 1528K->4K(3072K), 0.0008970 secs][Tenured: 5857K->3023K(6848K), 0.0019426 secs] 5914K->3023K(9920K), [Metaspace: 3279K->3279K(1056768K)], 0.0028739 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 1524K->1524K(3072K), 0.0000219 secs][Tenured: 5966K->2287K(6848K), 0.0068019 secs] 7491K->2287K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0071469 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] [GC (Allocation Failure) [ParNew: 1552K->0K(3072K), 0.0003459 secs][Tenured: 5230K->5230K(6848K), 0.0018971 secs] 6783K->5230K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0022837 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [Tenured: 5230K->5028K(6848K), 0.0023246 secs] 5230K->5028K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0023448 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap par new generation total 3072K, used 82K [0x00000000ff600000, 0x00000000ff950000, 0x00000000ff950000) eden space 2752K, 2% used [0x00000000ff600000, 0x00000000ff614818, 0x00000000ff8b0000) from space 320K, 0% used [0x00000000ff8b0000, 0x00000000ff8b0000, 0x00000000ff900000) to space 320K, 0% used [0x00000000ff900000, 0x00000000ff900000, 0x00000000ff950000) tenured generation total 6848K, used 5028K [0x00000000ff950000, 0x0000000100000000, 0x0000000100000000) the space 6848K, 73% used [0x00000000ff950000, 0x00000000ffe39298, 0x00000000ffe39400, 0x0000000100000000) Metaspace used 3310K, capacity 4496K, committed 4864K, reserved 1056768K class space used 361K, capacity 388K, committed 512K, reserved 1048576K java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:647) at java.lang.StringBuilder.append(StringBuilder.java:208) at gc7.GCDemo.main(GCDemo.java:34) Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release Process finished with exit code 0
并行回收GC(Pargllel)/(Parallel Scavenge)
Parallel Scavenge收集器类似ParNew也是一个新生代垃圾收集器,使用复制算法,也是一个并行的多线程的垃圾收集器,俗称吞吐量优先收集器。一句话:串行收集器在新生代和老年代的并行化
它关注的重点是:
可控制的吞吐量(Thoughput = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间) ),也即比如程序运行100分钟,垃圾收集时间1分钟,吞吐量就是99%。高吞吐量意味着高效利用CPU时间,它多用于在后台运算而不需要太多交互的任务。
自适应调节策略也是ParallelScavenge收集器与ParNew收集器的一个重要区别。(自适应调节策略:虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间( -XX:MaxGCPauseMills))或最大的吞吐量。
常用JVM参数:-XX:+UseParallelGC 或 -XX:+UseParallelOldGC(可互相激活) 使用Parallel Scanvenge收集器
开启该参数后:新生代使用复制算法,老年代使用标记-整理算法
多说一句:-XX:ParallelGCThreads=数字N表示启动多少个GC线程
cpu>8 N = 5/8
cpu<8 N=实际个数
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseParallelGc
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseParallelOldGc
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelGC (PSYoungGen+ParOldGen)
-XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC *******GCDemo hello [GC (Allocation Failure) [PSYoungGen: 2015K->510K(2560K)] 2015K->746K(9728K), 0.0017194 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 2519K->504K(2560K)] 2755K->1290K(9728K), 0.0007522 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 2010K->504K(2560K)] 2796K->2024K(9728K), 0.0007144 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 2010K->496K(2560K)] 4999K->4242K(9728K), 0.0008428 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 1269K->456K(2560K)] 6483K->5670K(9728K), 0.0006226 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 456K->472K(1536K)] 5670K->5686K(8704K), 0.0003144 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 472K->0K(1536K)] [ParOldGen: 5214K->2835K(7168K)] 5686K->2835K(8704K), [Metaspace: 3280K->3280K(1056768K)], 0.0039002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 30K->32K(2048K)] 5801K->5803K(9216K), 0.0007950 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 32K->32K(2048K)] 5803K->5803K(9216K), 0.0002756 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 32K->0K(2048K)] [ParOldGen: 5771K->4303K(7168K)] 5803K->4303K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0027395 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 19K->32K(2048K)] 5790K->5802K(9216K), 0.0004345 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 32K->32K(2048K)] 5802K->5802K(9216K), 0.0002537 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 32K->0K(2048K)] [ParOldGen: 5770K->2101K(7168K)] 5802K->2101K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0037370 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 19K->0K(2048K)] 6524K->6505K(9216K), 0.0003985 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Ergonomics) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 6505K->5037K(7168K)] 6505K->5037K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0018821 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] 5037K->5037K(9216K), 0.0002030 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 5037K->5017K(7168K)] 5037K->5017K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0041440 secs] [Times: user=0.05 sys=0.01, real=0.00 secs] Heap PSYoungGen total 2048K, used 60K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000) eden space 1024K, 5% used [0x00000000ffd00000,0x00000000ffd0f188,0x00000000ffe00000) from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) ParOldGen total 7168K, used 5017K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000) object space 7168K, 69% used [0x00000000ff600000,0x00000000ffae64f0,0x00000000ffd00000) Metaspace used 3310K, capacity 4496K, committed 4864K, reserved 1056768K class space used 361K, capacity 388K, committed 512K, reserved 1048576K java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:647) at java.lang.StringBuilder.append(StringBuilder.java:208) at gc7.GCDemo.main(GCDemo.java:34) Process finished with exit code 0
老年代
串行GC(Serial old)/(Serial MSC)
Serial Old是Serial垃圾收集器老年代版本,它同样是一个单线程的收集器,使用标记-整理算法,这个收集器也主要是运行在Client默认的Java虚拟机中默认的老年代垃圾收集器
在Server模式下,主要有两个用途(了解,版本已经到8及以后)
1.在JDK1.5之前版本中与新生代的Parallel Scavenge收集器搭配使用(Parallel Scavenge + Serial Old)
2.作为老年代版中使用CMS收集器的后备垃圾收集方案。
配置方法:
-Xms10m -Xmx10m -XX:PrintGCDetails -XX:+PrintConmandLineFlags -XX:+UseSerialOldlGC
Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. Unrecognized VM option 'UseSerialOldGC' Did you mean '(+/-)UseSerialGC'?
并行GC(Parallel Old)/(Parallel MSC)
Parallel Old收集器是Parallel Scavenge的老年代版本,使用多线程的标记-整理算法,Parallel Old收集器在JDK1.6才开始提供。
在JDK1.6之前,新生代使用ParallelScavenge收集器只能搭配老年代的Serial Old收集器,只能保证新生代的吞吐量优先,无法保证整体的吞吐量。在JDK1.6以前(Parallel Scavenge + Serial Old)
Parallel Old正是为了在老年代同样提供吞吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,JDK1.8后可以考虑新生代Parallel Scavenge和老年代Parallel Old 收集器的搭配策略。在JDK1.8及后(Parallel Scavenge + Parallel Old)
JVM常用参数:
-XX +UseParallelOldGC:使用Parallel Old收集器,设置该参数后,新生代Parallel+老年代 Parallel Old
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelOldGC (PSYoungGen+ParOldGen)
-XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelOldGC *******GCDemo hello [GC (Allocation Failure) [PSYoungGen: 2009K->510K(2560K)] 2009K->714K(9728K), 0.0014453 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 2517K->504K(2560K)] 2721K->1251K(9728K), 0.0010510 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 2006K->504K(2560K)] 2754K->1976K(9728K), 0.0007607 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 2025K->488K(2560K)] 4947K->4142K(9728K), 0.0010018 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 1252K->496K(2560K)] 6356K->5656K(9728K), 0.0006202 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 496K->480K(1536K)] 5656K->5672K(8704K), 0.0004318 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 480K->0K(1536K)] [ParOldGen: 5192K->2807K(7168K)] 5672K->2807K(8704K), [Metaspace: 3280K->3280K(1056768K)], 0.0048812 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Ergonomics) [PSYoungGen: 30K->0K(1536K)] [ParOldGen: 7156K->2082K(7168K)] 7186K->2082K(8704K), [Metaspace: 3280K->3280K(1056768K)], 0.0041772 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 19K->0K(2048K)] 6451K->6431K(9216K), 0.0003595 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Ergonomics) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 6431K->4981K(7168K)] 6431K->4981K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0021572 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] 4981K->4981K(9216K), 0.0003128 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 4981K->4961K(7168K)] 4981K->4961K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0042617 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap PSYoungGen total 2048K, used 50K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000) eden space 1024K, 4% used [0x00000000ffd00000,0x00000000ffd0c820,0x00000000ffe00000) from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) ParOldGen total 7168K, used 4961K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000) object space 7168K, 69% used [0x00000000ff600000,0x00000000ffad87c8,0x00000000ffd00000) Metaspace used 3310K, capacity 4496K, committed 4864K, reserved 1056768K class space used 361K, capacity 388K, committed 512K, reserved 1048576K java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:647) at java.lang.StringBuilder.append(StringBuilder.java:208) at gc7.GCDemo.main(GCDemo.java:43) Process finished with exit code 0
并发标记清除GC(CMS)
CMS收集器(Concurrent Mark Sweep:并发标记清除)是一种以最短回收停顿时间为目标的收集器
适合应用在互联网或者B/S系统的服务器上,这类应用尤其重视服务器的响应速度,希望系统停顿时间最短。
CMS非常适合堆内存大,CPU核数多的服务器端应用,也是G1出现之前大型应用的首选收集器。
Concurrent Mark Sweep:并发标记清除,并发收集低停顿,并发指的是与用户线程一起执行
开启该收集器的JVM参数: -XX:+UseConcMarkSweepGC 开启该参数后,会自动将 -XX:+UseParNewGC打开,开启该参数后,使用ParNew(young 区用)+ CMS(Old 区用) + Serial Old 的收集器组合,Serial Old将作为CMS出错的后备收集器
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC
4步过程
初始标记(CMS initial mark)
只是标记一个GC Roots 能直接关联的对象,速度很快,仍然需要暂停所有的工作线程
并发标记(CMS concurrent mark)和用户线程一起
进行GC Roots跟踪过程,和用户线程一起工作,不需要暂停工作线程。主要标记过程,标记全部对象
重新标记(CMS remark)
为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程
由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正
并发清除(CMS concurrent sweep)和用户线程一起
清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。基于标记结果,直接清理对象
由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,
所以总体上来看CMS收集器的内存回收和用户线程是一起并发地执行。
四步概述
优缺点
- 优点:
- 并发收集低停顿
- 缺点:并发执行,对CPU资源压力大
由于并发进行,CMS在收集与应用线程会同时增加对堆内存的占用,也就是说,CMS必须在老年代堆内存用尽之前完成垃圾回收,否则CMS回收失败时,将触发担保机制,串行老年代收集器将会以STW方式进行一次GC,从而造成较大的停顿时间
采用的标记清除算法会导致大量碎片
标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩,CMS也提供了参数 -XX:CMSFullGCSBeForeCompaction(默认0,即每次都进行内存整理)来指定多少次CMS收集之后,进行一次压缩的Full GC
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC (par new generation+ concurrent
-XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=3497984 -XX:MaxTenuringThreshold=6 -XX:NewSize=3497984 -XX:OldPLABSize=16 -XX:OldSize=6987776 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC *******GCDemo hello [GC (Allocation Failure) [ParNew: 2668K->320K(3072K), 0.0020081 secs] 2668K->904K(9920K), 0.0025972 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 2791K->187K(3072K), 0.0009650 secs] 3376K->1549K(9920K), 0.0010100 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 2835K->39K(3072K), 0.0010504 secs] 4197K->2873K(9920K), 0.0010873 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 1601K->34K(3072K), 0.0011454 secs] 4434K->4340K(9920K), 0.0012037 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (CMS Initial Mark) [1 CMS-initial-mark: 4305K(6848K)] 5812K(9920K), 0.0001466 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-mark-start] [GC (Allocation Failure) [ParNew: 1558K->36K(3072K), 0.0007581 secs][CMS[CMS-concurrent-mark: 0.001/0.009 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] (concurrent mode failure): 5777K->2849K(6848K), 0.0103252 secs] 5864K->2849K(9920K), [Metaspace: 3279K->3279K(1056768K)], 0.0111286 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] [GC (Allocation Failure) [ParNew: 1524K->1524K(3072K), 0.0000181 secs][CMS: 5793K->2110K(6848K), 0.0022030 secs] 7318K->2110K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0022655 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 1552K->0K(3072K), 0.0004090 secs][CMS: 5054K->5053K(6848K), 0.0029809 secs] 6606K->5053K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0034439 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [CMS: 5053K->5033K(6848K), 0.0028018 secs] 5053K->5033K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0028299 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (CMS Initial Mark) [1 CMS-initial-mark: 5033K(6848K)] 5033K(9920K), 0.0001571 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-mark-start] [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] [GC (CMS Final Remark) [YG occupancy: 54 K (3072 K)][Rescan (parallel) , 0.0001388 secs][weak refs processing, 0.0000152 secs][class unloading, 0.0002369 secs][scrub symbol table, 0.0004395 secs][scrub string table, 0.0000854 secs][1 CMS-remark: 5033K(6848K)] 5087K(9920K), 0.0009906 secs] [Times: user=0.00 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] Heap par new generation total 3072K, used 81K [0x00000000ff600000, 0x00000000ff950000, 0x00000000ff950000) eden space 2752K, 2% used [0x00000000ff600000, 0x00000000ff6147b0, 0x00000000ff8b0000) from space 320K, 0% used [0x00000000ff8b0000, 0x00000000ff8b0000, 0x00000000ff900000) to space 320K, 0% used [0x00000000ff900000, 0x00000000ff900000, 0x00000000ff950000) concurrent mark-sweep generation total 6848K, used 5033K [0x00000000ff950000, 0x0000000100000000, 0x0000000100000000) Metaspace used 3310K, capacity 4496K, committed 4864K, reserved 1056768K class space used 361K, capacity 388K, committed 512K, reserved 1048576K java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:647) at java.lang.StringBuilder.append(StringBuilder.java:208) at gc7.GCDemo.main(GCDemo.java:43) Process finished with exit code 0
垃圾收集器配置代码总结
底层代码
实际代码
package gc7; import java.util.Random; /** * @author CSDN@日星月云 * @date 2022/10/13 14:11 * * 1 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseSerialGC (DefNew+Tenured) * * 2 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC (ParNew+Tenured) * 备注情况:Java HotSpot(TM)64-Bit server VM warning: using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release * * 3 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelGC (PSYoungGen+ParOldGen) * * 4 * 4.1 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelOldGC (PSYoungGen+ParOldGen) * * 4.2不加就是默认UseParallelGC * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags (PSYoungGen+ParOldGen) * * 5 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC (par new generation+ concurrent * 6 * -Xms10m -Xmx10m -XX: +PrintGcDetails -XX:+PrintCommandLineFlags -XX: +UseG1GC 后面单独讲解G1 * * 7(理论知道即可,实际中已经被优化掉了,没有了。) * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseSerialOldGC * * * 下面是故意繁琐配置,主要是为了学习,一般生产不这么配置: * 下面是故意繁琐配置,主要是为了学习,一般生产不这么配置: * 下面是故意繁琐配置,主要是为了学习,一般生产不这么配置: * * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelGC -XX:+UseParallelOldGC (PSYoungGen+ParOldGen) * * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC -XX:+UseConcMarkSweepGC (par new generation+ concurrent * */ public class GCDemo { public static void main(String[] args) { System.out.println("*******GCDemo hello") ; try{ String str = "atguigu"; while(true){ str += str + new Random().nextInt(77777777)+new Random().nextInt(88888888); str.intern(); } }catch (Throwable e){ e .printStackTrace(); } } }
繁琐配置
* -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelGC -XX:+UseParallelOldGC (PSYoungGen+ParOldGen)
E:\environment\jdks\jdk8\bin\java.exe -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParallelGC -XX:+UseParallelOldGC "-javaagent:E:\IntelliJ IDEA 2021.1\lib\idea_rt.jar=1042:E:\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath E:\environment\jdks\jdk8\jre\lib\charsets.jar;E:\environment\jdks\jdk8\jre\lib\deploy.jar;E:\environment\jdks\jdk8\jre\lib\ext\access-bridge-64.jar;E:\environment\jdks\jdk8\jre\lib\ext\cldrdata.jar;E:\environment\jdks\jdk8\jre\lib\ext\dnsns.jar;E:\environment\jdks\jdk8\jre\lib\ext\jaccess.jar;E:\environment\jdks\jdk8\jre\lib\ext\jfxrt.jar;E:\environment\jdks\jdk8\jre\lib\ext\localedata.jar;E:\environment\jdks\jdk8\jre\lib\ext\nashorn.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunec.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunjce_provider.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunmscapi.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunpkcs11.jar;E:\environment\jdks\jdk8\jre\lib\ext\zipfs.jar;E:\environment\jdks\jdk8\jre\lib\javaws.jar;E:\environment\jdks\jdk8\jre\lib\jce.jar;E:\environment\jdks\jdk8\jre\lib\jfr.jar;E:\environment\jdks\jdk8\jre\lib\jfxswt.jar;E:\environment\jdks\jdk8\jre\lib\jsse.jar;E:\environment\jdks\jdk8\jre\lib\management-agent.jar;E:\environment\jdks\jdk8\jre\lib\plugin.jar;E:\environment\jdks\jdk8\jre\lib\resources.jar;E:\environment\jdks\jdk8\jre\lib\rt.jar;E:\IdeaProjects\JavaMS\out\production\second_2 gc7.GCDemo -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC -XX:+UseParallelOldGC *******GCDemo hello [GC (Allocation Failure) [PSYoungGen: 2034K->491K(2560K)] 2034K->707K(9728K), 0.0033883 secs] [Times: user=0.05 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 2453K->491K(2560K)] 2669K->1211K(9728K), 0.0009706 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 1967K->328K(2560K)] 2687K->1766K(9728K), 0.0006618 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 1804K->376K(2560K)] 4680K->3971K(9728K), 0.0008032 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 1134K->344K(2560K)] 6167K->5376K(9728K), 0.0005936 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 344K->400K(1536K)] 5376K->5432K(8704K), 0.0003837 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 400K->0K(1536K)] [ParOldGen: 5032K->2790K(7168K)] 5432K->2790K(8704K), [Metaspace: 3280K->3280K(1056768K)], 0.0047711 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 30K->32K(2048K)] 7133K->7135K(9216K), 0.0003780 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Ergonomics) [PSYoungGen: 32K->0K(2048K)] [ParOldGen: 7103K->2071K(7168K)] 7135K->2071K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0037254 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 19K->0K(2048K)] 6404K->6384K(9216K), 0.0003856 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Ergonomics) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 6384K->4946K(7168K)] 6384K->4946K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0025659 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] 4946K->4946K(9216K), 0.0002791 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 4946K->4926K(7168K)] 4946K->4926K(9216K), [Metaspace: 3280K->3280K(1056768K)], 0.0050133 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] Heap PSYoungGen total 2048K, used 60K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000) eden space 1024K, 5% used [0x00000000ffd00000,0x00000000ffd0f158,0x00000000ffe00000) from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) ParOldGen total 7168K, used 4926K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000) object space 7168K, 68% used [0x00000000ff600000,0x00000000ffacfb58,0x00000000ffd00000) Metaspace used 3310K, capacity 4496K, committed 4864K, reserved 1056768K class space used 361K, capacity 388K, committed 512K, reserved 1048576K java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:647) at java.lang.StringBuilder.append(StringBuilder.java:208) at gc7.GCDemo.main(GCDemo.java:53) Process finished with exit code 0
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC -XX:+UseConcMarkSweepGC (par new generation+ concurrent
E:\environment\jdks\jdk8\bin\java.exe -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags -XX:+UseParNewGC -XX:+UseConcMarkSweepGC "-javaagent:E:\IntelliJ IDEA 2021.1\lib\idea_rt.jar=11889:E:\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath E:\environment\jdks\jdk8\jre\lib\charsets.jar;E:\environment\jdks\jdk8\jre\lib\deploy.jar;E:\environment\jdks\jdk8\jre\lib\ext\access-bridge-64.jar;E:\environment\jdks\jdk8\jre\lib\ext\cldrdata.jar;E:\environment\jdks\jdk8\jre\lib\ext\dnsns.jar;E:\environment\jdks\jdk8\jre\lib\ext\jaccess.jar;E:\environment\jdks\jdk8\jre\lib\ext\jfxrt.jar;E:\environment\jdks\jdk8\jre\lib\ext\localedata.jar;E:\environment\jdks\jdk8\jre\lib\ext\nashorn.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunec.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunjce_provider.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunmscapi.jar;E:\environment\jdks\jdk8\jre\lib\ext\sunpkcs11.jar;E:\environment\jdks\jdk8\jre\lib\ext\zipfs.jar;E:\environment\jdks\jdk8\jre\lib\javaws.jar;E:\environment\jdks\jdk8\jre\lib\jce.jar;E:\environment\jdks\jdk8\jre\lib\jfr.jar;E:\environment\jdks\jdk8\jre\lib\jfxswt.jar;E:\environment\jdks\jdk8\jre\lib\jsse.jar;E:\environment\jdks\jdk8\jre\lib\management-agent.jar;E:\environment\jdks\jdk8\jre\lib\plugin.jar;E:\environment\jdks\jdk8\jre\lib\resources.jar;E:\environment\jdks\jdk8\jre\lib\rt.jar;E:\IdeaProjects\JavaMS\out\production\second_2 gc7.GCDemo -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=3497984 -XX:MaxTenuringThreshold=6 -XX:NewSize=3497984 -XX:OldPLABSize=16 -XX:OldSize=6987776 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC *******GCDemo hello [GC (Allocation Failure) [ParNew: 2736K->320K(3072K), 0.0017628 secs] 2736K->933K(9920K), 0.0018279 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 2758K->242K(3072K), 0.0008528 secs] 3371K->1448K(9920K), 0.0008789 secs] [Times: user=0.06 sys=0.01, real=0.00 secs] [GC (Allocation Failure) [ParNew: 2866K->7K(3072K), 0.0008856 secs] 4073K->2867K(9920K), 0.0009175 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 1530K->4K(3072K), 0.0011067 secs] 4390K->4334K(9920K), 0.0011248 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (CMS Initial Mark) [1 CMS-initial-mark: 4330K(6848K)] 5804K(9920K), 0.0001509 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-mark-start] [GC (Allocation Failure) [ParNew: 1526K->4K(3072K), 0.0008495 secs][CMS[CMS-concurrent-mark: 0.001/0.017 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] (concurrent mode failure): 5800K->2846K(6848K), 0.0190148 secs] 5856K->2846K(9920K), [Metaspace: 3279K->3279K(1056768K)], 0.0199122 secs] [Times: user=0.00 sys=0.00, real=0.02 secs] [GC (Allocation Failure) [ParNew: 1522K->1522K(3072K), 0.0000173 secs][CMS: 5786K->2108K(6848K), 0.0024578 secs] 7309K->2108K(9920K), [Metaspace: 3279K->3279K(1056768K)], 0.0025170 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [ParNew: 1551K->0K(3072K), 0.0003594 secs][CMS: 5048K->5047K(6848K), 0.0026833 secs] 6599K->5047K(9920K), [Metaspace: 3279K->3279K(1056768K)], 0.0030875 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (Allocation Failure) [CMS: 5047K->5028K(6848K), 0.0027164 secs] 5047K->5028K(9920K), [Metaspace: 3279K->3279K(1056768K)], 0.0027446 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (CMS Initial Mark) [1 CMS-initial-mark: 5028K(6848K)] 5028K(9920K), 0.0001343 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [CMS-concurrent-mark-start] [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] [GC (CMS Final Remark) [YG occupancy: 54 K (3072 K)][Rescan (parallel) , 0.0001939 secs][weak refs processing, 0.0000050 secs][class unloading, 0.0002255 secs][scrub symbol table, 0.0004376 secs][scrub string table, 0.0001002 secs][1 CMS-remark: 5028K(6848K)] 5082K(9920K), 0.0010318 secs] [Times: user=0.00 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] Heap par new generation total 3072K, used 109K [0x00000000ff600000, 0x00000000ff950000, 0x00000000ff950000) eden space 2752K, 3% used [0x00000000ff600000, 0x00000000ff61b648, 0x00000000ff8b0000) from space 320K, 0% used [0x00000000ff8b0000, 0x00000000ff8b0000, 0x00000000ff900000) to space 320K, 0% used [0x00000000ff900000, 0x00000000ff900000, 0x00000000ff950000) concurrent mark-sweep generation total 6848K, used 5028K [0x00000000ff950000, 0x0000000100000000, 0x0000000100000000) Metaspace used 3310K, capacity 4496K, committed 4864K, reserved 1056768K class space used 361K, capacity 388K, committed 512K, reserved 1048576K java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3332) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:647) at java.lang.StringBuilder.append(StringBuilder.java:208) at gc7.GCDemo.main(GCDemo.java:53) Process finished with exit code 0
如何选择垃圾收集器
组合的选择
单CPU或者小内存,单机程序
-XX:+UseSerialGC
多CPU,需要最大的吞吐量,如后台计算型应用
-XX:+UseParallelGC(这两个相互激活)
-XX:+UseParallelOldGC
多CPU,追求低停顿时间,需要快速响应如互联网应用
-XX:+UseConcMarkSweepGC
-XX:+ParNewGC
新生代使用复制算法
因为新生代对象的生存时间比较短,80%的都要回收的对象,采用标记-清除算法则内存碎片化比较严重,采用复制算法可以灵活高效,且便与整理空间。
老年代采用标记整理
标记整理算法主要是为了解决标记清除算法存在内存碎片的问题,又解决了复制算法两个Survivor区的问题,因为老年代的空间比较大,不可能采用复制算法,特别占用内存空间
最后
2022 10/13 15:36
p90~p100
Markdown 37795 字数 835 行数
HTML 36499 字数 541 段落