当我们在开发Java应用程序时,JVM的GC(垃圾回收)是一个非常重要的话题。GC的作用是回收不再使用的内存,以便程序可以继续运行。在JVM中,GC的日志记录了GC的详细信息,包括GC的类型、时间、内存使用情况等。在本文中,我们将介绍JVM GC日志的格式、含义和分析方法。
JVM GC日志的格式通常是一系列以时间戳为基础的事件,每个事件都包含了GC的详细信息。以下是一个典型的JVM GC日志的示例:
2021-01-01T00:00:00.000+0800: 1.000: [GC (Allocation Failure) 1.000: 1024K->512K(4096K), 0.0010000 secs]
其中,时间戳的格式为[ISO 8601],GC类型为“GC (Allocation Failure)”,GC发生的时间为1.000秒,GC前后内存使用情况分别为1024K和512K,总内存为4096K,GC耗时为0.001秒。
JVM GC日志包含了大量的信息,可以帮助我们了解JVM的内存使用情况和GC的性能。以下是一些常见的GC日志含义:
JVM GC日志的分析可以帮助我们了解JVM的内存使用情况和GC的性能,以便优化应用程序的性能。以下是一些常见的JVM GC日志分析方法:
JVM参数中加入GC日志的打印选型,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
我们针对于上述代码的内存进行分析,最开始我们定义和初始化了字节数组:new byte[1024 * 1024],并且对于同一个引用,我们分配了3个相同大小的字节数组,每个数组都是1MB。
public static void main(String[] args) {
byte[] arrayInit = new byte[1024 * 1024];
arrayInit = new byte[1024 * 1024];
arrayInit = null;
//触发Young GC
byte[] arrayInit2 = new byte[2 * 1024 * 1024];
}
byte[] arrayInit = new byte[1024 * 1024];。
在JVM的Eden区内存储一个1MB的对象,同时在main线程的栈中会压入一个main方法的栈帧,在main方法的栈帧内部,会有一个“arrayInit ”变量,这个变量是指向堆内存Eden区的那个1MB的数组。
接着我们看第二行代码
arrayInit = new byte[1024 * 1024];
当执行了这行代码之后,便会在堆中的Eden区中再次分配一个数组,并且让之前的局部变量指向第二个数组,然后第一个数组就没人引用了,此时第一个数组就成了没人引用的“垃圾对象”了,如下图所示。
接着我们来看第三行代码:array1 = null; 这行代码一执行,就让arrayInit 这个变量什么都不指向了,此时会导致之前创建的2个数组全部变成垃圾对象,如下图。
在项目的根路径下,就可以看到一个gc.log,点进去查看:
0.383: [GC (Allocation Failure) 0.384: [ParNew: 3543K->512K(4608K), 0.0024598 secs] 3543K->1828K(9728K), 0.0026607 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
0.386: [GC (Allocation Failure) 0.387: [ParNew: 2627K->0K(4608K), 0.0015255 secs] 3943K->1828K(9728K), 0.0015985 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
par new generation total 4608K, used 2089K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
eden space 4096K, 51% used [0x00000000ff600000, 0x00000000ff80a558, 0x00000000ffa00000)
from space 512K, 0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
to space 512K, 0% used [0x00000000ffa80000, 0x00000000ffa80000, 0x00000000ffb00000)
concurrent mark-sweep generation total 5120K, used 1828K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
Metaspace used 3101K, capacity 4620K, committed 4864K, reserved 1056768K
class space used 327K, capacity 392K, committed 512K, reserved 1048576K
从上面内容中可以看到进行了两次GC。
0.383: [GC (Allocation Failure)
0.384: [ParNew: 3543K->512K(4608K), 0.0024598 secs] 3543K->1828K(9728K), 0.0026607 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
从上面的内容可以得出:
0.386: [GC (Allocation Failure)
0.387: [ParNew: 2627K->0K(4608K), 0.0015255 secs] 3943K->1828K(9728K), 0.0015985 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
之后输出了Young GC之后的堆内存使用快照:
Heap
par new generation total 4608K, used 2089K [0x00000000ff600000, 0x00000000ffb00000, 0x00000000ffb00000)
eden space 4096K, 51% used [0x00000000ff600000, 0x00000000ff80a558, 0x00000000ffa00000)
from space 512K, 0% used [0x00000000ffa00000, 0x00000000ffa00000, 0x00000000ffa80000)
to space 512K, 0% used [0x00000000ffa80000, 0x00000000ffa80000, 0x00000000ffb00000)
concurrent mark-sweep generation total 5120K, used 1828K [0x00000000ffb00000, 0x0000000100000000, 0x0000000100000000)
Metaspace used 3101K, capacity 4620K, committed 4864K, reserved 1056768K
class space used 327K, capacity 392K, committed 512K, reserved 1048576K
可以看到新生代占用了2098KB(一个2M的数组,还有一点“未知内容”);Eden区被占用了51%,Survivor From和Survivor To使用率为0%,CMS管理的老年代被使用了1828KB。
JVM GC日志是一个非常重要的话题,可以帮助我们了解JVM的内存使用情况和GC的性能。通过分析JVM GC日志,我们可以优化应用程序的性能,提高应用程序的稳定性和可靠性。
链接:https://juejin.cn/post/7223684448074907706
页面更新:2024-06-10
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号