JVM 垃圾收集算法和垃圾收集器(下)

简介: 本文主要讲述垃圾收集算法和常用的几种垃圾收集器

垃圾收集器参数


参数 描述
UseSerialGC 虚拟机运行在Client模式下的默认值,打开此开关后,使用Serial + Serial Old 的收集器组合进行内存回收
UseParNewGC 打开此开关后,使用PerNew + Serial Old的收集器组合进行内存回收
UseConcMarkSweepGC 打开此快关后,使用PerNew + CMS + Serial Old 的收集器组合进行内存回收。Serial Old 收集器作为CMS收集器处理
UseParallelGC 失败后的后备收集器使用
UseParalleOldGC 虚拟机运行的Server模式下的默认值,打开此开关后,使用Parallel Scavenge + Serial Old (PS MarkSweep) 的收集器组合进行内存回收
SurvivorRatio 新生代中Eden区域与Surivivor 区域的容量比值, 默认为8, 代表 Eden: Surivivor = 8:1
PretenureSizeThreshold 直接晋升到老年代的对象大小, 设置这个参数后,大于这个参数的对象将直接在老年代分配
MaxTenuringThreshold 晋升到老年代的对象年龄。每个对象在坚持过一次Minor GC之后,年龄就增加1,当超过这个参数值就进入老年代
UseAdaptiveSizePolicy 动态调整Java堆中各个区域的大小以及进入老年代的年龄
HandlePromotionFailure 是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个Eden和Survivor区的所有对象都存活的极端情况
ParallelGCThreads 设置并行GC时惊醒内存回收的线程数
GCTimeRatio GC时间占总时间的比率,默认值为99,即允许1%的GC时间,仅在使用Parallel Scavenge收集器时生效
MaxGCPauseMillis 设置GC的最大停顿时间。仅在使用Parallel Scavenge 收集器时生效
CMSInitialingOccupancyFraction 设置CMS收集器在老年代空间被使用多少后触发垃圾收集。默认值为68% ,仅在使用CMS收集器时生效
UseCMSCompactionAtFullCollection 设置CMS收集器在完成垃圾回收后是否需要进行一次内存碎片整理,仅在使用CMS收集器时生效
CMSFullGCsBeforeCompaction 设置CMS后机器在进行若干次垃圾收集器后再启动一次内存碎片整理仅在使用CMS收集器时生效


GC 日志分析


ParallelGC 收集器 GC 日志分析


GC 日志


  • 代码案例


public class MyTest1 {
    public static void main(String[] args) {
        int size = 1024 * 1024;
        byte[] myAlloc1 = new byte[2 * size];
        byte[] myAlloc2 = new byte[2 * size];
        byte[] myAlloc3 = new byte[3 * size];
        //byte[] myAlloc4 = new byte[2 * size];
        System.out.println("hello world");
    }
}


  • 运行时JVM参数


-verbose:gc  //报告每个垃圾收集事件,输出虚拟机中垃圾回收的详细日志
-Xms20M      //初始化堆空间大小
-Xmx20M      //最大堆空间大小,-Xms和-Xmx设置成一样可以避免垃圾回收造成的抖动问题
-Xmn10M      //新生代内存大小
-XX:+PrintGCDetails //打印GC回收详细日志
-XX:SurvivorRatio=8 //新生代中Eden和Survivior的比例默认为8那么 Eden(对象发源地):Form Survivor:To Survivor = 8:1:1


  • GC日志


[GC (Allocation Failure) [PSYoungGen: 6195K->624K(9216K)] 6195K->4728K(19456K), 0.0083276 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
hello world
Heap
 PSYoungGen      total 9216K, used 4019K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 41% used [0x00000007bf600000,0x00000007bf950dd8,0x00000007bfe00000)
  from space 1024K, 60% used [0x00000007bfe00000,0x00000007bfe9c010,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 4104K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 40% used [0x00000007bec00000,0x00000007bf002020,0x00000007bf600000)
 Metaspace       used 3067K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 336K, capacity 388K, committed 512K, reserved 1048576K


  • GC日志解析


  • GC 标记表示触发了一次GC回收, 前面没有Full修饰,标明这是一个Minor GC,注意它不代表只是GC新生代,并且现有的不管是新生代还是老年代都会STW
  • Allocation Failure 表示年轻代没有足够的内存能够存储新的数据
  • PSYoungGen 表示本次GC发生在年轻代使用的是Parallel Scavenge 收集器
  • 6195K->624K(9216K) 表示新生代 6195 表示当前新生代已使用容量, 624 表示GC后的使用容量, 9216 表示该区域的总容量,单位:KB
  • 6195K->4728K(19456K) 表示总的堆内存 三个参数分别表示: 堆回收之前大小,堆回收后的大小,堆的总大小
  • 0.0083276 secs 表示GC耗时,单位是秒
  • [Times: user=0.01 sys=0.00, real=0.01 secs] 分别表示用户耗时,内核耗时,总耗时
  • PSYoungGen      total 9216K, used 4019K 表示新生代总内存 9216K, 已使用 4019K
  • eden space 8192K, 41% used , eden 区内存大小 8192K,已使用 41%
  • from space 1024K, 60% used , from Survivor 区内存大小 1024K,已使用 60%
  • to   space 1024K, 0% used  , eden Survivor 区内存大小 1024K,已使用 0%
  • ParOldGen       total 10240K, used 4104K 老年代的总内存大小10240K, 已使用 4104K
  • 新生代回收内存:6195-624  = 5571k  //执行完gc后,新生代执行垃圾回收后堆空间回收内存
  • 实际的回收内存:6195-4728 = 1467k  //执行完gc后,总的堆空间释放的容量
  • 年老代使用内存:5571-1467 = 4104k  (新生代的释放内存:会分为1.新生代->老年代,2.真实被回收)


Full GC


GC 日志


[GC (Allocation Failure) [PSYoungGen: 6195K->614K(9216K)] 6195K->4710K(19456K), 0.0127704 secs] [Times: user=0.01 sys=0.01, real=0.01 secs] 
[GC (Allocation Failure) --[PSYoungGen: 6999K->6999K(9216K)] 11095K->15199K(19456K), 0.0106521 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6999K->2489K(9216K)] [ParOldGen: 8200K->8192K(10240K)] 15199K->10681K(19456K), [Metaspace: 3070K->3070K(1056768K)], 0.0075955 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
hello world
Heap
 PSYoungGen      total 9216K, used 4977K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 60% used [0x00000007bf600000,0x00000007bfadc7a8,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 8192K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 80% used [0x00000007bec00000,0x00000007bf4000d8,0x00000007bf600000)
 Metaspace       used 3150K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 346K, capacity 388K, committed 512K, reserved 1048576K


  • Full GC 一般是年老代触发的GC


  • Ergonomics 是以种标识,


  • PSYoungGen: 6933K->3507K(9216K) ,采用Parallel Scavenge 新生代垃圾收集器


  • ParOldGen: 7176K->7168K(10240K) ,采用Parallel Old 老年代垃圾收集器 ,老年代的对象增多,是由于部分来自新生代


  • Metaspace: 元空间


注意


  • 在新生代内存不足的时候,但是遇到了大对象会直接存储到老年代中。


CMS 收集器 GC 日志分析


JVM 参数设置


-verbose:gc
-Xms20M
-Xmx20M
-Xmn10M
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
-XX:+UseConcMarkSweepGC //设置使用CMS回收器


CMS 收集器的 GC 日志


[GC (CMS Initial Mark) [1 CMS-initial-mark: 8194K(10240K)] 12935K(19456K), 0.0004987 secs] [Times: user=0.00 sys=0.01, real=0.00 secs] 
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.000/0.000 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: 4741 K (9216 K)][Rescan (parallel) , 0.0010423 secs][weak refs processing, 0.0000103 secs][class unloading, 0.0003310 secs][scrub symbol table, 0.0006947 secs][scrub string table, 0.0001765 secs][1 CMS-remark: 8194K(10240K)] 12935K(19456K), 0.0023344 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]



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5天前
|
存储 算法 Java
深入浅出JVM(十八)之并发垃圾收集器G1
深入浅出JVM(十八)之并发垃圾收集器G1
|
5天前
|
存储 算法 Java
深入浅出JVM(十七)之并发垃圾收集器CMS
深入浅出JVM(十七)之并发垃圾收集器CMS
|
5天前
|
算法 Java
深入浅出JVM(十五)之垃圾收集器(上篇)
深入浅出JVM(十五)之垃圾收集器(上篇)
|
5天前
|
安全 算法 Java
深入浅出JVM(十三)之垃圾回收算法细节
深入浅出JVM(十三)之垃圾回收算法细节
|
5天前
|
存储 算法 Java
深入浅出JVM(十二)之垃圾回收算法
深入浅出JVM(十二)之垃圾回收算法
|
5天前
|
算法 Java PHP
JVM 的垃圾回收机制以及垃圾回收算法的详解
JVM 的垃圾回收机制以及垃圾回收算法的详解
10 0
|
7天前
|
Arthas 监控 算法
JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了垃圾回收算法评价标准、标记清除算法、复制算法、标记整理算法、分代垃圾回收算法等内容。
19 0
JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法
|
20天前
|
算法 Java
JVM 垃圾回收算法(重要)
JVM 垃圾回收算法(重要)
|
1月前
|
存储 缓存 算法
深度解析JVM世界:垃圾判断和垃圾回收算法
深度解析JVM世界:垃圾判断和垃圾回收算法
|
1月前
|
算法 Java UED
【五一创作】值得一看的JVM垃圾收集器
【五一创作】值得一看的JVM垃圾收集器