1.-Xmx和-Xms
-Xms:-Xms
指定了JVM启动时堆的初始大小。JVM会在启动时预分配这么多内存给堆空间,这个值可以设置得与-Xmx
相等,这样做可以避免应用运行时频繁地调整堆大小,从而提高性能。(java虚拟机为什么建议把-Xms和-Xmx设置相等?-CSDN博客)
-Xmx:-Xmx
指定了堆能够使用的最大内存大小。当应用中的对象数量增加,需要更多的堆内存时,JVM会尝试扩展堆空间,直到达到-Xmx
指定的限制为止。如果堆空间达到了-Xmx
指定的最大值,还需要更多内存时,就会抛出OutOfMemoryError
。
例如,如果你想要设置初始堆大小为256MB,最大堆大小为1GB,可以在启动JVM时使用以下参数:
java -Xms256m -Xmx1024m -jar your-application.jar
合理地设置这两个参数对于优化Java应用的性能非常关键。
- 太小的堆大小可能会导致频繁的垃圾回收,影响性能;
- 而太大的堆大小则可能导致垃圾回收暂停时间过长,也会影响到性能。
- 此外,过大的
-Xmx
设置还可能会导致系统资源的浪费。因此,需要根据应用的实际需求和运行环境来合理配置这两个参数。
2.-Xmn、-XX:NewRatio、-XX:SurvivorRatio:
- -Xmn :设置新生代大小
- -XX:NewRatio 新生代(eden+2*s)和老年代(不包含永久区)的比值
例如:4,表示新生代:老年代=1:4,即新生代占整个堆的1/5
- -XX:SurvivorRatio(幸存代),设置两个Survivor区和eden的比值.
例如:8,表示两个Survivor:eden=2:8,即一个Survivor占年轻代的1/10
3.-XX:+PrintGC
-XX:+PrintGC:打印比较简单的gc日志
2.1如下图,在idea设置相关虚拟机参数
2.2代码模拟垃圾回收
解释下控制台的GC日志:
[GC (System.gc()) 208986K->122582K(307712K), 0.0118668 secs]
- 触发原因:这条日志显示的是由
System.gc()
触发的一次垃圾收集。尽管是通过System.gc()
触发的,但这次GC的具体类型(Minor GC或Full GC)取决于JVM的垃圾收集器及其决定。 - 类型:这次GC可能是一次Minor GC,也就是只清理年轻代(Young Generation)的垃圾收集。但由于是通过
System.gc()
触发的,实际上很可能是JVM决定执行更全面的清理。 - 内存回收:内存从208986K减少到122582K,释放了约86.4MB的内存。
- 持续时间:这次垃圾收集耗时约0.012秒。
[Full GC (System.gc()) 122582K->18487K(307712K), 0.1503007 secs]
- 触发原因:同样是由
System.gc()
触发的。Full GC
表示这是一次全堆垃圾收集,包括年轻代、老年代(Old Generation)以及永久代或元空间(取决于使用的Java版本)。 - 类型:Full GC是最彻底的垃圾收集,它会暂停应用线程(Stop-The-World),清理整个Java堆和方法区,以回收尽可能多的空间。
- 内存回收:内存从122582K减少到18487K,释放了约104.1MB的内存。
- 持续时间:这次垃圾收集耗时约0.150秒,比前一次GC时间长。这是因为Full GC更为彻底,需要检查整个堆,因此耗时更长。
4.-XX:+PrintGCDetails
-XX:+PrintGCDetails:打印详细GC日志。
idea虚拟机参数的设置方法参照-XX:+PrintGC中,代码也是和上面的一致。
解释下控制台的GC日志:
[GC (System.gc()) [PSYoungGen: 88429K->6817K(128512K)]
207590K->125985K(316928K), 0.0110152 secs]
[Times: user=0.00 sys=0.00, real=0.01 secs]
第一个事件:Minor GC
- 触发原因:通过
System.gc()
手动触发。 - PSYoungGen:年轻代在GC前使用了约86.4MB(88429K),GC后减少到约6.7MB(6817K)。年轻代的总容量为约125.5MB(128512K)。
- 堆内存使用变化:整个堆在GC前使用了约202.7MB(207590K),GC后减少到约123.0MB(125985K)。堆的总容量为约309.3MB(316928K)。
- GC耗时:大约0.011秒。
- CPU时间:用户模式和系统模式下的CPU时间几乎为零,实际耗时为0.01秒,表明GC过程主要是并行执行的。
第二个事件:Full GC
[Full GC (System.gc()) [PSYoungGen: 6817K->0K(128512K)]
[ParOldGen: 119168K->18469K(188416K)] 125985K->18469K(316928K),
[Metaspace: 38844K->38844K(1085440K)], 0.1565366 secs]
[Times: user=0.28 sys=0.02, real=0.16 secs]
- 触发原因:通过
System.gc()
手动触发。 - PSYoungGen:年轻代在GC前使用了约6.7MB(6817K),GC后减少到0K。年轻代的总容量仍为约125.5MB(128512K)。
- ParOldGen:老年代在GC前使用了约116.2MB(119168K),GC后减少到约18MB(18469K)。老年代的总容量为约183.9MB(188416K)。
- 堆内存使用变化:整个堆在GC前使用了约123.0MB(125985K),GC后减少到约18MB(18469K)。堆的总容量仍为约309.3MB(316928K)。
- Metaspace:元空间(用于存储类元数据的区域)在GC前后使用量保持不变,约37.9MB(38844K)。元空间的总容量为约1054.4MB(1085440K)。
- GC耗时:大约0.156秒。
- CPU时间:用户模式下耗时0.28秒,系统模式下耗时0.02秒,实际耗时为0.16秒,表明GC过程可能涉及更多的计算和内存管理操作。
5.-XX:+HeapDumpOnOutOfMemoryError和
-XX:HeapDumpPath
-XX:+HeapDumpOnOutOfMemoryError:内存溢出时导出整个堆信息
-XX:HeapDumpPath:指定导出堆的存放路径。
演示代码如下:
由于我在虚拟机设置的xmx是20M,代码循环20次,每次分配3M的内存,必要会内存溢出。
运行结果:
6.-Xloggc
-Xloggc:<file>
是一个Java虚拟机(JVM)的启动参数,用于指定垃圾收集(GC)日志的输出文件。当你设置这个参数时,JVM会将垃圾收集的详细日志写入你指定的文件中,这对于分析和调优GC性能非常有用。
使用-Xloggc
参数的基本格式如下:
Windows环境:-Xloggc:C:\logs\gc.log
Linux或Mac环境:-Xloggc:/var/logs/gc.log
-Xloggc
参数只指定了GC日志的输出位置,要激活详细的GC日志,可能还需要结合使用其他GC日志相关的参数,如-XX:+PrintGCDetails
。不过,从Java 9开始,-Xloggc
和-XX:+PrintGCDetails
等参数被新的统一的日志系统-Xlog
所替代,提供了更加灵活的日志管理功能。
例如,在Java 9及更高版本中,你可以使用类似下面的命令来代替-Xloggc
和-XX:+PrintGCDetails
的组合:
-Xlog:gc*:file=<file_path>
结束!!!