第二季:7.怎么查看服务器默认的垃圾收集器是那个?生产上如何配置垃圾收集器的?谈谈你对垃圾收集器的理解?【Java面试题】

前言


2022 10/13 13:32

路漫漫其修远兮,吾将上下而求索


本文是根据尚硅谷学习所做笔记

仅供学习交流使用,转载注明出处


推荐

尚硅谷Java大厂面试题第2季,面试必刷,跳槽大厂神器

第二季大佬总结

7.怎么查看服务器默认的垃圾收集器是那个?生产上如何配置垃圾收集器的?谈谈你对垃圾收集器的理解?

说明

本文目录前是相关视频的名字和具体视频中思维导图的名字

题目

7.怎么查看服务器默认的垃圾收集器是那个?
生产上如何配置垃圾收集器的?
谈谈你对垃圾收集器的理解?

0037

怎么查看默认的垃圾收集器是那个?

0538


```java
E:\IdeaProjects\JavaMS\second_2\src\jvm2>java -XX:+PrintCommandLineFlags -version

-XX:InitialHeapSize=123581248 -XX:MaxHeapSize=1977299968 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedO
ops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

移动到最后一句,就能看到 -XX:+UseParallelGC 说明使用的是并行垃圾回收

-XX:+UseParallelGC

默认的垃圾收集器有哪些?

Java中一共有7大垃圾收集器

  • UseSerialGC:串行垃圾收集器
  • UseParallelGC:并行垃圾收集器
  • UseConcMarkSweepGC:(CMS)并发标记清除
  • UseParNewGC:年轻代的并行垃圾回收器
  • UseParallelOldGC:老年代的并行垃圾回收器
  • UseG1GC:G1垃圾收集器
  • UseSerialOldGC:串行老年代垃圾收集器(已经被移除)

底层源码

请添加图片描述

package gc7;

/**
 * @author CSDN@日星月云
 * @date 2022/10/13 13:40
 * -XX:+UseSerialGC
 */
public class HelloGC {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("HelloGC");
        Thread.sleep(Integer.MAX_VALUE);
    }
}

E:\IdeaProjects\JavaMS\second_2\src\jvm2>jinfo -flag UseSerialGC 19920
-XX:+UseSerialGC

E:\IdeaProjects\JavaMS\second_2\src\jvm2>jinfo -flag UseParallelGC 19920
-XX:-UseParallelGC

默认

E:\IdeaProjects\JavaMS\second_2\src\jvm2>jinfo -flag UseParallelGC 19340
-XX:+UseParallelGC

E:\IdeaProjects\JavaMS\second_2\src\jvm2>jinfo -flag UseSerialGC 19340
-XX:-UseSerialGC

垃圾收集器

0111

新生代使用的:

  • Serial Copying: UserSerialGC,串行垃圾回收器
  • Parallel Scavenge:UserParallelGC,并行垃圾收集器
  • ParNew:UserParNewGC,新生代并行垃圾收集器

老年区使用的:

  • Serial Old:UseSerialOldGC,老年代串行垃圾收集器
  • Parallel Compacting(Parallel Old):UseParallelOldGC,老年代并行垃圾收集器
  • CMS:UseConcMarkSwepp,并行标记清除垃圾收集器

各区都能使用的:

  • G1:UseG1GC,G1垃圾收集器

垃圾收集器就来具体实现这些GC算法并实现内存回收,不同厂商,不同版本的虚拟机实现差别很大,HotSpot中包含的收集器如下图所示:

0551

部分参数预先说明

  • DefNew:Default New Generation
  • Tenured:Old
  • ParNew:Parallel New Generation
  • PSYoungGen:Parallel Scavenge
  • ParOldGen:Parallel Old Generation

Server/Client模式分别是什么意思

  1. 使用范围:一般使用Server模式,Client模式基本不会使用

  2. 操作系统

    1. 32位的Window操作系统,不论硬件如何都默认使用Client的JVM模式
    2. 32位的其它操作系统,2G内存同时有2个cpu以上用Server模式,低于该配置还是Client模式
    3. 64位只有Server模式

新生代

串行GC(Serial)/(Serial copying)

串行GC(Serial)(Serial Copying)

是一个单线程单线程的收集器,在进行垃圾收集时候,必须暂停其他所有的工作线程直到它收集结束。

0135
串行收集器是最古老,最稳定以及效率高的收集器,只使用一个线程去回收但其在垃圾收集过程中可能会产生较长的停顿(Stop-The-World 状态)。 虽然在收集垃圾过程中需要暂停所有其它的工作线程,但是它简单高效,对于限定单个CPU环境来说,没有线程交互的开销可以获得最高的单线程垃圾收集效率,因此Serial垃圾收集器依然是Java虚拟机运行在Client模式下默认的新生代垃圾收集器

对应JVM参数是:-XX:+UseSerialGC

开启后会使用:Serial(Young区用) + Serial Old(Old区用) 的收集器组合

表示:新生代、老年代都会使用串行回收收集器,新生代使用复制算法,老年代使用标记-整理算法

-Xms10m -Xmx10m -XX:PrintGCDetails -XX:+PrintConmandLineFlags -XX:+UseSerialGC
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:+UseSerialGC  (DefNew+Tenured)

-XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseSerialGC 
*******GCDemo hello
[GC (Allocation Failure) [DefNew: 2736K->320K(3072K), 0.0016750 secs] 2736K->913K(9920K), 0.0017270 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 2762K->184K(3072K), 0.0011492 secs] 3356K->1374K(9920K), 0.0011808 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 2811K->0K(3072K), 0.0012172 secs] 4001K->2845K(9920K), 0.0012486 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 1524K->0K(3072K), 0.0009369 secs] 4370K->4317K(9920K), 0.0009559 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 1524K->0K(3072K), 0.0009298 secs][Tenured: 5789K->3028K(6848K), 0.0022375 secs] 5842K->3028K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0031982 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 1524K->1524K(3072K), 0.0000205 secs][Tenured: 5972K->2292K(6848K), 0.0027519 secs] 7497K->2292K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0028218 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 1553K->0K(3072K), 0.0003477 secs][Tenured: 5236K->5236K(6848K), 0.0019966 secs] 6790K->5236K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0024124 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [Tenured: 5236K->5029K(6848K), 0.0023700 secs] 5236K->5029K(9920K), [Metaspace: 3280K->3280K(1056768K)], 0.0023923 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 3072K, used 109K [0x00000000ff600000, 0x00000000ff950000, 0x00000000ff950000)
  eden space 2752K,   3% used [0x00000000ff600000, 0x00000000ff61b650, 0x00000000ff8b0000)
  from space 320K,   0% used [0x00000000ff8b0000, 0x00000000ff8b0000, 0x00000000ff900000)
  to   space 320K,   0% used [0x00000000ff900000, 0x00000000ff900000, 0x00000000ff950000)
 tenured generation   total 6848K, used 5029K [0x00000000ff950000, 0x0000000100000000, 0x0000000100000000)
   the space 6848K,  73% used [0x00000000ff950000, 0x00000000ffe394f0, 0x00000000ffe39600, 0x0000000100000000)
 Metaspace       used 3311K, 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:32)

Process finished with exit code 0

并行GC(ParNew)

因为Serial 和 ParNew都不推荐使用了,因此现在新生代默认使用的是Parallel Scavenge,也就是新生代和老年代都是使用并行

ParNew(并行)收集器

一句话:使用多线程进行垃圾回收,在垃圾收集时,会Stop-the-World暂停其他所有的工作线程直到它收集结束。

0247

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出现之前大型应用的首选收集器。

0139

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

垃圾收集器配置代码总结

底层代码

0244

实际代码
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

0210

新生代使用复制算法
因为新生代对象的生存时间比较短,80%的都要回收的对象,采用标记-清除算法则内存碎片化比较严重,采用复制算法可以灵活高效,且便与整理空间。

老年代采用标记整理
标记整理算法主要是为了解决标记清除算法存在内存碎片的问题,又解决了复制算法两个Survivor区的问题,因为老年代的空间比较大,不可能采用复制算法,特别占用内存空间

最后


2022 10/13 15:36


p90~p100


Markdown 37795 字数 835 行数
HTML 36499 字数 541 段落


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日星月云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值