【JVM】之 动手模拟 YoungGC

文章目录

    • 一、动手模拟`YoungGC`
      • (1)示例代码
      • (2)运行过程
      • (3)运行后,分析gc日志
    • 二、GC日志说明
      • (1)堆使用情况

一、动手模拟YoungGC


以下是 :JDK 1.8版本

// JVM 参数运行
-XX:NewSize=5242880 -XX:MaxNewSize=5242880 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=10485760 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log
  • -XX:InitialHeapSize:初始堆大小,堆内存 10MB
  • -XX:MaxHeapSize:最大堆大小,5MB
  • -XX:NewSize: 初始新生代大小,5MB
  • -XX:PretenureSizeThreshold=10485760:指定了大对象阈值 10MB

新生代使用ParNew垃圾回收器,老年代使用CMS垃圾回收器

如图:

【JVM】之 动手模拟 YoungGC_第1张图片

  • -XX:+PrintGCDetails: 打印详细的gc日志
  • -XX:+PrintGCTimeStamps: 打印每次GC发生的时间
  • -Xloggc:gc.log: 设置将gc日志写入一个磁盘文件

(1)示例代码

public class Demo {
    public static void main(String[] args) {
        byte[] array1 = new byte[1024*1024];
        array1 = new byte[1024*1024];
        array1 = new byte[1024*1024];
        array1 = null;
        
        byte[] array2 = new byte[2 * 1024 * 1024];
    }
}

代码的意思:

  • new byte[1024*1024]:连续创建3个数组,每个数组都是 1MB
  • array1:这个局部变量依次引用这三个对象,最后把array1这个局部变量指向null

(2)运行过程

  1. byte[] array1 = new byte[1024*1024];

如图:

【JVM】之 动手模拟 YoungGC_第2张图片

  1. array1 = new byte[1024*1024];

如图:

【JVM】之 动手模拟 YoungGC_第3张图片

  1. array1 = new byte[1024*1024];

如图:

【JVM】之 动手模拟 YoungGC_第4张图片

  1. array1 = null;

如图:

【JVM】之 动手模拟 YoungGC_第5张图片

  1. byte[] array2 = new byte[2 * 1024 * 1024];

此时分配一个2MB大小的数组,尝试放入 Eden区中

然而Eden总共 4MB,而且里面已经放入 3MB (3个1MB的数组),所以只剩下 1MB 空间。

所以这时候会触发 新生代 Young GC


(3)运行后,分析gc日志

运行后,gc日志如下:

OpenJDK 64-Bit Server VM (25.162-b12) for linux-amd64 JRE (1.8.0_162-8u162-b12-1-b12), built on Mar 15 2018 17:19:50 by "buildd" with gcc 7.3.0
Memory: 4k page, physical 16306976k(7355368k free), swap 2097148k(2097148k free)
CommandLine flags: -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=5242880 -XX:NewSize=5242880 -XX:OldPLABSize=16 -XX:PretenureSizeThreshold=10485760 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:+UseParNewGC 
0.116: [GC (Allocation Failure) 0.116: [ParNew: 3623K->413K(4608K), 0.0037366 secs] 3623K->1439K(9728K), 0.0038102 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
Heap
 par new generation   total 4608K, used 3603K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
  eden space 4096K,  77% used [0x00000000ff600000, 0x00000000ff91d860, 0x00000000ffa00000)
  from space 512K,  80% used [0x00000000ffa80000, 0x00000000ffae7560, 0x00000000ffb00000)
  to   space 512K,   0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
 concurrent mark-sweep generation total 5120K, used 1026K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
 Metaspace       used 3197K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 343K, capacity 388K, committed 512K, reserved 1048576K



二、GC日志说明


0.116: [GC (Allocation Failure) 0.116: [ParNew: 3623K->413K(4608K), 0.0037366 secs] 3623K->1439K(9728K), 0.0038102 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 

这个概要说明了本次GC的执行情况。

  • GC (Allocation Failure):对象分配失败

  • 0.116: 系统运行以后过了多少秒发生了本次GC

  • ParNew: 3623K->413K(4608K) 0.0037366 secs:

  • 新生代可用空间:4608KB == 4.5MB,一个Eden(4MB) + 一个Survivor(0.5MB)
  • 3623K -> 413K: 新生代执行一次 GC,GC之前 3623KB,GC之后 413KB存活下来
  • 0.0037366: 本次GC消耗的时间
  • 3623K->1439K(9728K), 0.0038102 secsJava堆内存的情况
  • 9728KB(9.5MB): Java堆内存总可用空间
  • 3623KB: GC之前 Java堆内存里使用了 3623KB, 之后使用了 1439KB

(1)堆使用情况

Heap
 par new generation   total 4608K, used 3603K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
  eden space 4096K,  77% used [0x00000000ff600000, 0x00000000ff91d860, 0x00000000ffa00000)
  from space 512K,  80% used [0x00000000ffa80000, 0x00000000ffae7560, 0x00000000ffb00000)
  to   space 512K,   0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
 concurrent mark-sweep generation total 5120K, used 1026K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
 Metaspace       used 3197K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 343K, capacity 388K, committed 512K, reserved 1048576K
  • par new generation total 4608K, used 3603K

ParNew垃圾回收器负责的新生代,总共 4608KB(4.5MB), 目前使用了 3603KB

  • eden space 4096K, 77% used

Eden 4MB内存使用了 77%

  • from space 512K, 80%

From Survivor区,512KB,使用了 80%

  • concurrent mark-sweep generation total 5120K, used 1026K

Concurrent Mark-Sweep垃圾回收器(CMS垃圾回收器),管理的老年代内存空间一共是 5MB,此时使用了 1026KB

  • Metaspace used 3197K, capacity 4496K, committed 4864K, reserved 1056768K

元数据空间

  • used, 使用了 3197KB
  • capacity, 真实可使用的大小 4496KB
  • committed, 向系统实际申请了大小 4864KB
  • reserved,从系统中预定了 1056768KB
  • class space used 343K, capacity 388K, committed 512K, reserved 1048576K

class空间

你可能感兴趣的:(【JVM】)