3.1、JVM学习——GC日志含义与配置

前言

GC 日志可以提供虚拟机各分代垃圾回收的情况,需要注意的是,不同的垃圾回收器在GC 日志中名字并不相同。

JDK 版本

本文使用 JDK 1.8 x64 进行相关测试

查看垃圾回收器

查看 JVM 垃圾回收器类型的三个方式

测试代码

从实践来说,可以通过限制虚拟机内存大小,然后不断创建对象来触发 GC,也可以直接调用 System.gc(),本文采用了后者——更简单,直观。
当然,作为测试,我们还是增加了一些JVM 的配置参数,用于日志能够展示在控制台上

-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728

public class GcTest {
		//-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
		private static final int _1MB = 1024 * 1024;
		private static final int _4MB = 4*1024 * 1024;

		/**
		 * 小对象先保存到 新生代 Eden
		 */
	    public static void testThreshold(){
	        byte[] allocation;
	        allocation = new byte[1 * _1MB];
	    }
	    
	    /**
	     * 大对象直接进入老年代
	     * -XX:PretenureSizeThreshold=3145728
	     */
	    public static void testPretenureSizeThreshold(){
	        byte[] allocation;
	        allocation = new byte[1 * _4MB];
	    }

	    public static void main(String[] args) {
	    	//触发老年代GC
	    	for(int j=0;j<3;j++) {
	    		testPretenureSizeThreshold();
	    	}
	    	
	    	//触发新生代GC
	    	for(int i=0;i<10;i++) {
	    		GcTest.testThreshold();
	    	}
	    	
	    	//手动触发GC
			System.gc();	
	    }
}

控制台内容

控制台内容包含了两个部分,第一个部分是 GC 信息,第二个部分是 Heap 信息
其中 GC 信息就是本文要介绍的GC 日志。
Heap 信息属于PrintGCDetails 的附加信息。

[GC (System.gc()) [PSYoungGen: 1740K->729K(9216K)] 1740K->737K(19456K), 0.0016883 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 729K->0K(9216K)] [ParOldGen: 8K->596K(10240K)] 737K->596K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0053865 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

内容解析-GC 信息

[GC (System.gc()) [PSYoungGen: 1740K->729K(9216K)] 1740K->737K(19456K), 0.0016883 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 729K->0K(9216K)] [ParOldGen: 8K->596K(10240K)] 737K->596K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0053865 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 

GC 日志以是否Stop The World 分为两类

GC 日志可以分为两种,一种是 [GC开头,一种是 [Full GC开头,二者的区别在于,[Full GC表明该垃圾回收过程发生了 Stop The World,需要强调的是,不要将GC 日志中 Full GC 关键字和 老年代的垃圾回收 Full GC 混淆,在GC 日志中 年轻代和老年代的日志是在一起的。

如果垃圾回收是由 Java 代码 System.gc()来触发的,则GC 日志中会增加一个(System.gc()),如本文的 [GC (System.gc()) 和 [Full GC (System.gc())
如果垃圾回收是由于内存空间不够,则会显示分配失败 [GC (Allocation Failure)
此外还会有其他类型的情况

[GC````和``[Full GC中间部分的含义:PsYoungGen 是年轻代的垃圾回收信息
ParOldGen是老年代的垃圾回收信息
Metaspace是元空间的垃圾回收信息
最后一部分 Times 表示垃圾回收期间各部分时间段占用的事件比重

比如 [PSYoungGen: 729K->0K(9216K)]
表示:新生代使用的是 ParallelGC 这种垃圾回收器,新生代总大小为 9216K,垃圾回收前后的内存占用大小为 729K->0K ,即所占用的 729K 空间全部被回收了

不同垃圾回收器日志关键字不同

GC 日志使用不同的关键字来区分不同的垃圾回收期,你应该了解到虚拟机垃圾回收器有多种不同的搭配方式。本文在下面内容中通过不同的VM 配置对不同情况下的GC日志关键字进行归纳总结。

新生代、老年代垃圾回收器的搭配连线图(CMS 是可以和 Serial Old 同时使用的)

在这里插入图片描述

内容解析-Heap 信息

Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

Heap 信息还是很明显的,PSYoungGen 表示年轻代垃圾回收器为 Parallel Scavenge,此外还有年轻代的 eden 、from、to 的信息;ParOldGen 表示老年代垃圾回收器为 Parallel Old,Metaspace 表示元数据信息,
total 表示总大小,used 表示已用

通过 Heap 信息,也可以分辨出来当前所用的是何种垃圾回收器

指定垃圾回收器与GC 关键字

通过参数指定垃圾回收器

参数描述
-XX:+UseSerialGCdef new generation (Serial)
-XX:+UseParNewGCpar new generation
-XX:+UseParallelGCPSYoungGen
-XX:+UseParallelOldGCPSYoungGen
-XX:+UseConcMarkSweepGC (CMS)par new generation

其他参数延伸

直接看 https://blog.csdn.net/maosijunzi/article/details/46562489

参数类型值举例描述好玩的周边
-Dfile.encoding启动参数=UTF-8影响文件内容,不设定就会采用操作系统的字符集,如果和编译时字符集不一致,就会造成乱码 法国服务器使用中国编译代码出现中文乱码问题
-Dsun.jnu.encoding启动参数=UTF-8影响类名以及输入参数的编码sun.jnu.encoding会影响入参
-Djava.io.tmpdir启动参数/tmp操作系统缓存的临时目录tomcat-临时目录问题
-Djava.net.preferIPv4Stack启动参数false协议栈设置,默认false,为默认值false时,在支持IPv6的双栈系统上,使用Java的Socket会默认通过底层native方法创建一个IPv6 Socket,这个IPv6 Socket可以同时支持和IPv4或IPv6主机通信。如果设置为true,Java程序将无法使用IPv6进行网络通信,也就是仅支持IPv4看下一行
-Djava.net.preferIPv6Addresses启动参数fasle默认false,为默认值false时,IPv4地址会优先使用,例如在DNS通过域名查询IP地址时,会优先使用IPv4地址,反之设为true,则会优先使用IPv6地址Java 设置Ipv4和Ipv6 决定InetAddress.getByName(“www.google.com”),InetAddress.getLocalHost() 返回是否IPV6
-Xss启动参数512K每个线程分配的内存大小栈溢出 StackOverflowError
-Xmx启动参数2g程序运行期间,最大可占用内存This value must a multiple of 1024 greater than 2MB,否则会报 OutOfMemory
-Xms启动参数2g程序启动时占用内存大小,理论上,设置越大,程序启动越快
-XX:MetaspaceSize启动参数256mmatesaceGC发生的初始阈值JVM参数MetaspaceSize的误解
-XX:MaxMetaspaceSiz启动参数256mMeta区容量范围为[20.8m, MaxMetaspaceSize)JVM 元空间扩容和FC的规律
-XX:+AlwaysPreTouch启动参数非赋值配置服务启动的时候真实的分配物理内存给jvm,否则会先配置虚拟内存,实际使用时再配置会降低运行速度,但是配置后启动速度会受影响运行期优化以及G1的特殊问题
-XX:ReservedCodeCacheSize启动参数240m设置codecache的大小,JIT编译后代码临时存储位置,满的话会优化甚至停止JIT,CPU升高,可以用 jconsole 查看codecache 足以引发量级的性能问题
-XX:+HeapDumpOnOutOfMemoryError启动参数非赋值配置JVM发生OOM时,自动生成DUMP文件内存溢出快照查看
-XX:HeapDumpPath启动参数/opt/user/tmp/HeapDump配合 HeapDumpOnOutOfMemoryError 使用,Heap 快照文件的存储位置可以用 jvisulevm 查看 快照文件
-XX:+UseG1GC启动参数非赋值配置使用 G1 GC,全称为 Garbage-First Garbage CollectorG1的一些概念
-XX:G1HeapRegionSize=4M启动参数1M-32M,需为2的幂次方倍,默认2MG1分配内存大小的基本单位G1的young gc\mixed gc\full gc
-XX:InitiatingHeapOccupancyPercent启动参数40,默认45G1 开始并发标记周期时 Perm Gen 占比的阈值,如果设置太大可能导致回收不及时退化为full gc,太小则可能频繁标记G1优化
-XX:MaxGCPauseMillis启动参数100,默认200,单位msGC最大停顿时间不要设置太小,否则会频繁的停顿,造成服务不可用
-XX:+TieredCompilation启动参数非赋值配置分层编译,非赋值配置
-XX:CICompilerCount启动参数4最大并行编译数tomcat 重启负载高问题定位
-XX:-UseBiasedLocking启动参数非赋值配置禁用偏向锁。偏向锁可以提高有同步但没有竞争的程序性能。但是如果锁对象时常被多条线程竞争,那偏向锁就是多余的JVM 偏向锁是如何实现的
-XX:+PrintGCDetails启动参数非赋值配置打印GC详细信息本文有大量GC的例子
-XX:+PrintGCDateStamps启动参数非赋值配置时间格式使用系统时间JVM打印更易读的时间格式
-XX:+PrintGCTimeStamps启动参数非赋值配置JVM自启动到打印日期的时间秒数+PrintGCTimeStamps 展示JVM启动秒数
-XX:+PrintAdaptiveSizePolicy启动参数非赋值配置打印JVM动态调整的各分区大小,ParallelScavenge 会自动调整各分区大小为什么From/To space 大小几乎变成0了呢
-XX:+PrintGCApplicationStoppedTime启动参数非赋值配置打印JVM被停止持续的时间打印GC暂停的时间
-XX:+PrintHeapAtGC启动参数非赋值配置每一次GC后都打印堆信息JVM GC 后打印堆信息
-XX:+PrintStringTableStatistics启动参数非赋值参配置打印字符串常量池统计信息,在GC日志中会多一栏StringTable statistics:字符串常量池日志
-XX:+PrintTenuringDistribution启动参数非赋值配置展示对象晋升到老年代经历GC的次数GC日志打印对象晋升老年代经历GC的次数
-Xloggc启动参数/opt/logs/jvm/gc.logGC日志目录和名称配置GC日志滚动被覆盖问题
-XX:+UseGCLogfileRotation -XX:NumberOfGCLogfiles=N -XX:GCLogfileSize=N符合配置日志循环打印,即产生多个GC日志文件,需要结合下面两个命令使用,即单文件大小,以及循环文件个数,默认文件数为0,大小0 ,即都不做限制,单个GC文件单位为M,建议值为循环30,单个文件30M为什么不推荐使用循环打印日志方式 循环打印GC日志配置
-XX:+PrintFlagsFinal启动参数非赋值配置打印系统所有参数JVM 系统参数查看
-XX:ErrorFile启动参数/opt/logs/jvm/hs_err_pid.logJVM 错误日志JVM参数设置
java_command启动参数./demo.jar使用命令行运行jar
java_class_path启动参数./demo,jar系统类加载器加载字节码class的路径java.class.path详解
11111
-XX:+AlwaysPreTouch运行参数非配置类型服务启动的时候真实的分配物理内存给jvm,会导致启动变慢,

垃圾回收器关键字规律总结

配置年轻代老年代元数据
-XX:+UseSerialGCdef new generationtenured generationMetaspace
-XX:+UseParNewGCpar new generationtenured generationMetaspace
-XX:+UseParallelGCPSYoungGenParOldGenMetaspace
-XX:+UseParallelOldGCPSYoungGenParOldGenMetaspace
-XX:+UseConcMarkSweepGCpar new generationconcurrent mark-sweep generationMetaspace

GC 详情展示

-XX:+UseSerialGC

垃圾回收器: Serial+ SerialOld
GC 日志

[GC (Allocation Failure) [Tenured: 8192K->596K(10240K), 0.0034819 secs] 9932K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0035603 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 7331K->0K(9216K), 0.0003829 secs] 12024K->4692K(19456K), 0.0004152 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [Tenured: 4692K->596K(10240K), 0.0031400 secs] 7928K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0031873 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

堆信息

 Heap
 def new generation   total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  eden space 8192K,   1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
  from space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
  to   space 1024K,   0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
 tenured generation   total 10240K, used 596K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
   the space 10240K,   5% used [0x00000007bf600000, 0x00000007bf6950e8, 0x00000007bf695200, 0x00000007c0000000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseParNewGC

垃圾回收器: PawNew+64位时 SerialOld
GC 日志

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
[GC (Allocation Failure) [Tenured: 8192K->596K(10240K), 0.0045567 secs] 9932K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0046114 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [ParNew: 7331K->0K(9216K), 0.0005674 secs] 12024K->4692K(19456K), 0.0006037 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [Tenured: 4692K->596K(10240K), 0.0024158 secs] 7928K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0024644 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 

堆信息

Heap
 par new generation   total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  eden space 8192K,   1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
  from space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
  to   space 1024K,   0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
 tenured generation   total 10240K, used 596K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
   the space 10240K,   5% used [0x00000007bf600000, 0x00000007bf6950e8, 0x00000007bf695200, 0x00000007c0000000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseParallelGC

垃圾回收器: Parallel Scavenge+Parallel Old
GC 日志

[GC (Allocation Failure) [PSYoungGen: 7884K->745K(9216K)] 16076K->8946K(19456K), 0.0018850 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 8077K->681K(9216K)] 16277K->8882K(19456K), 0.0015061 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (System.gc()) [PSYoungGen: 2025K->665K(9216K)] 10225K->8874K(19456K), 0.0010182 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
[Full GC (System.gc()) [PSYoungGen: 665K->0K(9216K)] [ParOldGen: 8208K->594K(10240K)] 8874K->594K(19456K), [Metaspace: 2679K->2679K(1056768K)], 0.0052985 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 

堆信息

Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2683K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseParallelOldGC

垃圾回收器: Parallel Scavenge+Parallel Old
GC 日志

[GC (Allocation Failure) [PSYoungGen: 7884K->729K(9216K)] 16076K->8930K(19456K), 0.0018887 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 8061K->713K(9216K)] 16261K->8914K(19456K), 0.0014337 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (System.gc()) [PSYoungGen: 2057K->633K(9216K)] 10257K->8842K(19456K), 0.0010012 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 633K->0K(9216K)] [ParOldGen: 8208K->594K(10240K)] 8842K->594K(19456K), [Metaspace: 2679K->2679K(1056768K)], 0.0047913 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 

堆信息

Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseConcMarkSweepGC

垃圾回收器: ParNew+CMS
GC 日志

[GC (Allocation Failure) [CMS: 8192K->600K(10240K), 0.0039740 secs] 9932K->600K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0040636 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 7331K->0K(9216K), 0.0005220 secs] 12028K->4696K(19456K), 0.0005620 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [CMS: 4696K->599K(10240K), 0.0022873 secs] 7932K->599K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0023498 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

堆信息

Heap
 par new generation   total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  eden space 8192K,   1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
  from space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
  to   space 1024K,   0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
 concurrent mark-sweep generation total 10240K, used 600K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 2683K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值