1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > JVM优化系列-详解常用的虚拟机调优参数

JVM优化系列-详解常用的虚拟机调优参数

时间:2020-10-09 08:09:00

相关推荐

JVM优化系列-详解常用的虚拟机调优参数

导语

需要对虚拟机进行诊断,首先需要了解如何进行虚拟机的配合和跟踪,这里就来说说有那些虚拟机配置参数,通过它们来对虚拟机进行跟踪和配置。

文章目录

虚拟机跟踪调试参数如何读懂虚拟机日志GC基本参数分析GC发生的时间跟踪系统内引用关系类加载/卸载跟踪系统参数查看堆的配置参数最大堆和初始堆的设置新生代配置简单小例子场景1 使用默认的内存分配(不配置任何的堆内存控制)场景2 使用设置新生代-Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2场景3 设置新生代-Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2启动场景4 设置新生代-Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=8 启动场景5 使用-XX:NewRatio=老年代/新生代总结

虚拟机跟踪调试参数

在虚拟机的运行过程中,如果可以有效的跟踪其运行的轨迹,那么对后续问题的排查就会有一定的帮助,所以在JVM的设计上就提供了一些跟踪系统状态的参数,使用给定的参数执行Java虚拟机,虚拟机在运行的时候就可以打印相关的日志,这样就可以对出现的问题进行跟踪了。

如何读懂虚拟机日志

Java语言除了跨平台的优势以外,还有一个优势就是JVM虚拟机的GC,也就是自动垃圾回收机制,但是有的时候如果垃圾回收机制过于频繁就会出现占用CPU时间较长的情况,了解GC垃圾收集器的都知道。无论是那种垃圾回收机制在回收垃圾的时候都会停止一段时间来进行垃圾回收。这里就来说说最为基本的一个垃圾回收参数。

GC基本参数

-XX:+PrintGC

使用这个参数之后,JVM只要遇到的GC,就会打印出对应的日志。

-XX:+PrintGCDetails

使用这个参数会看到详细的GC回收信息,并且会使虚拟机在退出之前打印堆的详细信息,详细信息描述了当前堆的各个区间的使用情况。

-XX:+PrintHeapAtGC

这参数会在每次GC前后分别打印堆的信息,例如在上面参数最后输出的一样。

分析GC发生的时间

-XX:PrintGCTimeStamps

这个参数会在每次GC发生的时候,额外的输出GC发生的时间,该时间为虚拟机启动后的时间偏移量。

由于在GC执行的过程中会引起应用程序的停顿,所以还需要关注应用程序的执行时间和停顿时间。这个时候下面这个参数就会用到

-XX:+PrintGCApplicationConcurrentTime

这个参数可以打印应用程序执行时间

-XX:+PrintGCApplicationStoppedTime

这个参数可以打印应用程序由于GC而产生的停顿时间。

跟踪系统内引用关系

如果想跟踪系统内的软引用、弱引用、虚引用和Finallize队列,则可以使用打开这些信息的开关

-XX:+PrintReferenceGC

跟踪系统内的软引用、弱引用、虚引用和Finallize队列

在默认情况下GC的日志会在控制台输出,但是不便于后续分析和定位问题,所以虚拟机可以将GC日志以文件的形式输出,可以使用参数-Xloggc 指定。例如使用参数-Xlogg:log/gc.log 启动虚拟机,可以在当前目录下的log文件夹下的gc.log文件中记录所有的GC日志。

类加载/卸载跟踪

Java程序的运行离不开类的加载,系统加载的类存在于每个操作系统的文件系统中,以jar的形式打包或者以class文件的形式存在,可以直接通过文件系统进行查看。但是后来就出现了动态代理、AOP等技术,系统在运行过程中可能会加载一些动态生成的类,这些类比较隐蔽,没有办法通过文件系统找到,所以虚拟机提供了类加载、跟踪、卸载的参数就会格外的有意义。

-verbose:class

通过这个参数跟踪类加载与卸载的信息,当然也可以使用下面这个参数

-XX:+TraceClassLoading

使用这个参数来跟踪类加载的信息

-XX:+TraceClassUnloading

使用这个参数来跟踪类的卸载信息。

Java虚拟机还允许研发人员在运行时打印、查看系统中类的分布情况,只要在系统启动时加上-XX:+PrintClassHistogram参数。然后在Java的控制台中按下 Ctrl+Break 组合键,控制台上就会显示当前的类信息柱状图。

系统参数查看

由于Java虚拟机目前支持的众多的可配置参数,不同的参数可能对系统的执行效果有较大的影响,所以,如果有必要的情况下要明确实际的运行参数,虚拟机就提供了一些方法来让开发人员获得这些参数

-XX:+PrintVMOptions

可以在程序运行时,打印虚拟机接受到的命令行显式参数。

-XX:+PrintCommandLineFlags

可以打印传递给虚拟机的显式参数和隐式参数,隐式参数未必是通过命令行直接给出的,它可能是虚拟机启动的时候进行自己获取的设置的。

-XX:PrintFlagsFinal

它会打印所有系统参数值,所以需要查看系统的详细参数,应该使用这个参数,开启这个参数之后虚拟机可能会产生500多行的输出,每一行为一个配置参数和其当前取值。

堆的配置参数

堆空间是JVM中最为重要的一个组成部分,几乎所有的应用都和这块内存空间有关,在下面就来介绍一下关于堆内存有关的配置。

最大堆和初始堆的设置

当Java进程启动的时候,虚拟机机会分配给一块初始的堆空间,可以使用参数-Xms指定这块空间的大小,一般来说,虚拟机会尽可能维持在初始堆空间的范围内运行,但是如果初始堆空间耗尽,虚拟机将会对堆空间进行扩展,然后扩展并不是无限的而是有个界限的,这个时候就需要另外一个参数-Xmx指定,

示例

public class HeapAlloc{public static void main(String[] args){System.out.print("maxMemory=");System.out.println(Runtime.getRuntime().maxMemory()+" bytes");System.out.print("free mem=");System.out.println(Runtime.getRuntime().freeMemory()+" bytes");System.out.print("totalMemory=");System.out.println(Runtime.getRuntime().totalMemory()+" bytes");byte[] b = new byte[1*1024*1024];System.out.println("分配1M空间给数组");System.out.print("maxMemory=");System.out.println(Runtime.getRuntime().maxMemory()+" bytes");System.out.print("free mem=");System.out.println(Runtime.getRuntime().freeMemory()+" bytes");System.out.print("totalMemory=");System.out.println(Runtime.getRuntime().totalMemory()+" bytes");b = new byte[4*1024*1024];System.out.println("分配4M空间给数组");System.out.print("maxMemory=");System.out.println(Runtime.getRuntime().maxMemory()+" bytes");System.out.print("free mem=");System.out.println(Runtime.getRuntime().freeMemory()+" bytes");System.out.print("totalMemory=");System.out.println(Runtime.getRuntime().totalMemory()+" bytes");}}

从上面图中可以看到在在运行时的堆内存发生了变化,在上面提到的,最大内存就是指-Xmx的取值,而当前总内存也就是初始化的内存应该不小于-Xms设定的值,因为当使用的总内存是在这两个值之间,从-Xms开始向上增加所以空闲的内存就是当前内存减去已经使用的空间。当然这个就是一个形象的理解,并不能作为确定的值。例如如果在刚刚的代码上执行如下的操作

java -Xmx20M -Xms5M -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC HeapAlloc

简单分析(这里是结合我分配的内存以及代码来进行分析)

上述内容中再程序运行初期,显示的空闲内存是4.5MB,设置的初始化总内存是5MB,在进行完成1MB的内存分配之后,最大内存不变,总内存依然是5MB,因为它够用来分配1MB的对象,现在空闲的内存是3.5MB。第二步当申请分配一个4MB的对象的时候,剩余的内存不够了,所以对堆内存进行了扩展变为10MB,空闲的内存大约是3.5MB。

运行结果

localhost:heapalloc nihui$ java -Xmx20M -Xms5M -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC HeapAlloc-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC maxMemory=20316160 bytesfree mem=5566008 bytestotalMemory=6094848 bytes分配1M空间给数组maxMemory=20316160 bytesfree mem=4517416 bytestotalMemory=6094848 bytes[GC (Allocation Failure) [DefNew: 1540K->192K(1856K), 0.0017413 secs][Tenured: 1115K->1306K(4096K), 0.0008546 secs] 1540K->1306K(5952K), [Metaspace: 2614K->2614K(1056768K)], 0.0026266 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 分配4M空间给数组maxMemory=20316160 bytesfree mem=4792232 bytestotalMemory=10358784 bytesHeapdef new generation total 1920K, used 51K [0x00000007bec00000, 0x00000007bee10000, 0x00000007bf2a0000)eden space 1728K, 2% used [0x00000007bec00000, 0x00000007bec0cdd0, 0x00000007bedb0000)from space 192K, 0% used [0x00000007bedb0000, 0x00000007bedb0000, 0x00000007bede0000)to space 192K, 0% used [0x00000007bede0000, 0x00000007bede0000, 0x00000007bee10000)tenured generation total 8196K, used 5402K [0x00000007bf2a0000, 0x00000007bfaa1000, 0x00000007c0000000)the space 8196K, 65% used [0x00000007bf2a0000, 0x00000007bf7e6918, 0x00000007bf7e6a00, 0x00000007bfaa1000)Metaspace used 2621K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576Klocalhost:heapalloc nihui$

可以看到,当前最大的内存由-XX:MaxHeapSize=20971520 指定,这个值刚好是20M,而最大的可用内存maxMemory=20316160 bytes,可以看到这个值比设置的值要略微的小一些,这个是因为分配给堆内存的空间和实际的内存空间并非是同一个概念,由于垃圾回收机制的需要,虚拟机会对堆空间进行分区管理 ,不同的区域采用不同的回收算法,这个在后续的分享中会说到。这里分析一下实际情况

第一步 运行初始化

由于在运行的时候添加了 -XX:+PrintCommandLineFlag 参数,所以命令行的信息被全部打印出来了。会发现初始化的堆内存确实是5MB,最大内存是20MB 由这两个参数来确定,-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520

-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC

第二步 执行第一次打印操作

maxMemory=20316160 bytesfree mem=5566008 bytestotalMemory=6094848 bytes

第一次打印的时候会发现最大的内存与实际上设置的内存由一定的出入,而设置的初始化内存与实际初始化内存有误差,而我们设置的初始化的对内存大小实际上变成了空闲空间的大小。

第三步 执行对象分配之后打印结果

分配1M空间给数组maxMemory=20316160 bytesfree mem=4517416 bytestotalMemory=6094848 bytes执行第四步之前打印 GC信息[GC (Allocation Failure) [DefNew: 1540K->192K(1856K), 0.0017413 secs][Tenured: 1115K->1306K(4096K), 0.0008546 secs] 1540K->1306K(5952K), [Metaspace: 2614K->2614K(1056768K)], 0.0026266 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

 &emps;与第一次打印结果相比较,最大的堆内存空间没有发生变化,但是空闲空间少了1MB。但是这里有个问题,就是GC出现了Allocation Failure ,这里先来简单的解读一下这个GC怎么来看

GC

表明进行了一次垃圾回收,前面没有Full修饰,表明这是一次Minor GC ,注意它不表示只GC新生代,并且现有的不管是新生代还是老年代都会STW。

Allocation Failure

表明本次引起GC的原因是因为在年轻代中没有足够的空间能够存储新的数据了。

DefNew

表明本次GC发生在年轻代

1540K->192K(1856K), 0.0017413 secs(其他地方与之类似)

分别表示为:GC前该内存区域使用容量,GC后该内存区域使用容量,该内存区域总容量,GC执行的时间。

Tenured

表明老年代的GC操作。

Metaspace

表示Java8 元数据空间GC

Times

表示执行时间

user=0.00 sys=0.00, real=0.00 secs

是分别表示用户态耗时,内核态耗时和总耗时

第四步 第二次分配对象执行结果打印

分配4M空间给数组maxMemory=20316160 bytesfree mem=4792232 bytestotalMemory=10358784 bytes

结合上面的内容发现最大内存没有发生变化,而空闲内存的大小变成了4.7MB,而初始化内存空间的大小也发生了变化,这里简单的做个计算,首先分配了1MB的空间加上后面分配的4MB的空间,这样在第一次创建之后剩余空间无法创建一个4MB的的对象,这样就需要进行垃圾回收重新分配内存,就会导致在新生代上分配对象不够而进行GC操作。

第五步 结束打印堆内信息

Heapdef new generation total 1920K, used 51K [0x00000007bec00000, 0x00000007bee10000, 0x00000007bf2a0000)eden space 1728K, 2% used [0x00000007bec00000, 0x00000007bec0cdd0, 0x00000007bedb0000)from space 192K, 0% used [0x00000007bedb0000, 0x00000007bedb0000, 0x00000007bede0000)to space 192K, 0% used [0x00000007bede0000, 0x00000007bede0000, 0x00000007bee10000)tenured generation total 8196K, used 5402K [0x00000007bf2a0000, 0x00000007bfaa1000, 0x00000007c0000000)the space 8196K, 65% used [0x00000007bf2a0000, 0x00000007bf7e6918, 0x00000007bf7e6a00, 0x00000007bfaa1000)Metaspace used 2621K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576K

在结束之后会打印出整个的堆内存信息。下面就来测试一下一个新的场景

保证上面代码不发生改变,将启动参数变为如下内容

java -Xmx20M -Xms10M -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC HeapAllo

localhost:heapalloc nihui$ java -Xmx20M -Xms10M -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC HeapAlloc-XX:InitialHeapSize=10485760 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC maxMemory=20316160 bytesfree mem=9577088 bytestotalMemory=10158080 bytes分配1M空间给数组maxMemory=20316160 bytesfree mem=8528496 bytestotalMemory=10158080 bytes分配4M空间给数组maxMemory=20316160 bytesfree mem=4334176 bytestotalMemory=10158080 bytesHeapdef new generation total 3072K, used 1646K [0x00000007bec00000, 0x00000007bef50000, 0x00000007bf2a0000)eden space 2752K, 59% used [0x00000007bec00000, 0x00000007bed9bb30, 0x00000007beeb0000)from space 320K, 0% used [0x00000007beeb0000, 0x00000007beeb0000, 0x00000007bef00000)to space 320K, 0% used [0x00000007bef00000, 0x00000007bef00000, 0x00000007bef50000)tenured generation total 6848K, used 4096K [0x00000007bf2a0000, 0x00000007bf950000, 0x00000007c0000000)the space 6848K, 59% used [0x00000007bf2a0000, 0x00000007bf6a0010, 0x00000007bf6a0200, 0x00000007bf950000)Metaspace used 2620K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576Klocalhost:heapalloc nihui$

这个时候就会发现在第一次分配对象之后第二次分配对象并没有发生GC操作。也就是说实际的空间是够用的,这里还会看到Eden区的使用率是59%,老年代使用率为59%,而在上面的内容中Eden区的使用率为2%,老年代使用率为65%。

新生代配置

对于上面的内容可以看到在在第一种情况下启动在创建4MB的空间的时候会发生一次垃圾回收,这里需要强调的是这次垃圾回收是因为新生代内存不够了。那么如何调整新生代呢?

可以通过参数-Xmn来设置新生代的大小,设置一个较大的新生代会减小老年代的大小,这个系统参数对系统性能以及GC行为有很大的影响,新生代的大小一般调整为整个对空间的1/3到1/4左右。

参数-XX:SurvivorRatio用来设置新生代中eden空间和from/to空间的比例关系,如下

-XX:SurvivorRatio=eden/from=eden/to

简单小例子

下面这段代码是表示执行10此循环,并且每次循环开辟1MB的空间。

public class NewSizeDemo{public static void main(String[] args){byte[] b = null;for (int i = 0;i<10;i++) {b = new byte[1*1024*1024];System.out.println("第 "+i+"次创建完成");}}}

下面就来看看使用不同的堆内存配置策略来执行这段代码,然后来观察整个的运行过程中对于内存的影响

场景1 使用默认的内存分配(不配置任何的堆内存控制)

在这里虽然是默认内存分配,但是为了演示方便,将之前示例中的内存分配作为这里的分配原则。 也就是最大为20MB,初始化内存为20MB

java -Xmx20M -Xms20M -XX:+PrintGCDetails NewSizeDemo

运行结果

localhost:newsizedemo nihui$ java -Xmx20M -Xms20M -XX:+PrintGCDetails NewSizeDemo第 0次创建完成第 1次创建完成第 2次创建完成第 3次创建完成[GC (Allocation Failure) [PSYoungGen: 4675K->512K(6144K)] 4675K->1560K(19968K), 0.0013310 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 第 4次创建完成第 5次创建完成第 6次创建完成第 7次创建完成第 8次创建完成[GC (Allocation Failure) [PSYoungGen: 5742K->496K(6144K)] 6790K->2592K(19968K), 0.0009740 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 第 9次创建完成HeapPSYoungGentotal 6144K, used 1743K [0x00000007bf980000, 0x00000007c0000000, 0x00000007c0000000)eden space 5632K, 22% used [0x00000007bf980000,0x00000007bfab7fb8,0x00000007bff00000)from space 512K, 96% used [0x00000007bff80000,0x00000007bfffc010,0x00000007c0000000)to space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)ParOldGen total 13824K, used 2096K [0x00000007bec00000, 0x00000007bf980000, 0x00000007bf980000)object space 13824K, 15% used [0x00000007bec00000,0x00000007bee0c020,0x00000007bf980000)Metaspace used 2620K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576Klocalhost:newsizedemo nihui$

默认场景中,eden 与 form、to两个区域的默认配置eden 5632K from 512K,新生代总大小6656K。但是实际上是6144K ,少了512K。

分析执行过程

 第一次执行分配,总大小是6144K,分配1024K,剩余5120K

 第二次执行分配,总大小是5120K,分配1024K,剩余4096K

 第三次执行分配,总大小是4096K,分配1024K, 剩余3072K

 第四次执行分配,总大小是3072K,分配1024K,剩余2048K

实际上发生了一次GC,这里而经过前四次分配只占用了4096K的空间,在执行垃圾回收的时候实际上打印出来的数据是4675K,少了579K。

从上面的内容来看,在执行垃圾回收机制的时候并不是把所有的内存都清空,而是有一部分用来标识某些操作。

场景2 使用设置新生代-Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2

java -Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails NewSizeDemo

运行结果

localhost:newsizedemo nihui$ java -Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails NewSizeDemoJava HotSpot(TM) 64-Bit Server VM warning: NewSize (1536k) is greater than the MaxNewSize (1024k). A new max generation size of 1536k will be used.第 0次创建完成第 1次创建完成第 2次创建完成第 3次创建完成第 4次创建完成第 5次创建完成第 6次创建完成第 7次创建完成第 8次创建完成第 9次创建完成HeapPSYoungGentotal 1024K, used 495K [0x00000007bfe80000, 0x00000007c0000000, 0x00000007c0000000)eden space 512K, 96% used [0x00000007bfe80000,0x00000007bfefbc40,0x00000007bff00000)from space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)to space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)ParOldGen total 18944K, used 10240K [0x00000007bec00000, 0x00000007bfe80000, 0x00000007bfe80000)object space 18944K, 54% used [0x00000007bec00000,0x00000007bf6000a0,0x00000007bfe80000)Metaspace used 2620K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576Klocalhost:newsizedemo nihui$

场景3 设置新生代-Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2启动

java -Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails NewSizeDemo

运行结果

localhost:newsizedemo nihui$ java -Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails NewSizeDemo第 0次创建完成第 1次创建完成第 2次创建完成[GC (Allocation Failure) [PSYoungGen: 3678K->1504K(5632K)] 3678K->1520K(18944K), 0.0013394 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 第 3次创建完成第 4次创建完成第 5次创建完成[GC (Allocation Failure) [PSYoungGen: 4656K->1520K(5632K)] 4672K->1560K(18944K), 0.0012234 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 第 6次创建完成第 7次创建完成第 8次创建完成[GC (Allocation Failure) [PSYoungGen: 4672K->1520K(5632K)] 4712K->1588K(18944K), 0.0007138 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 第 9次创建完成HeapPSYoungGentotal 5632K, used 2706K [0x00000007bf900000, 0x00000007c0000000, 0x00000007c0000000)eden space 4096K, 28% used [0x00000007bf900000,0x00000007bfa289b0,0x00000007bfd00000)from space 1536K, 98% used [0x00000007bfd00000,0x00000007bfe7c020,0x00000007bfe80000)to space 1536K, 0% used [0x00000007bfe80000,0x00000007bfe80000,0x00000007c0000000)ParOldGen total 13312K, used 68K [0x00000007bec00000, 0x00000007bf900000, 0x00000007bf900000)object space 13312K, 0% used [0x00000007bec00000,0x00000007bec11010,0x00000007bf900000)Metaspace used 2620K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576Klocalhost:newsizedemo nihui$

场景4 设置新生代-Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=8 启动

java -Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=8 -XX:+PrintGCDetails NewSizeDemo

运行结果

localhost:newsizedemo nihui$ java -Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=8 -XX:+PrintGCDetails NewSizeDemo第 0次创建完成第 1次创建完成第 2次创建完成第 3次创建完成第 4次创建完成第 5次创建完成第 6次创建完成第 7次创建完成第 8次创建完成第 9次创建完成HeapPSYoungGentotal 13824K, used 11223K [0x00000007bf100000, 0x00000007c0000000, 0x00000007c0000000)eden space 12288K, 91% used [0x00000007bf100000,0x00000007bfbf5f00,0x00000007bfd00000)from space 1536K, 0% used [0x00000007bfe80000,0x00000007bfe80000,0x00000007c0000000)to space 1536K, 0% used [0x00000007bfd00000,0x00000007bfd00000,0x00000007bfe80000)ParOldGen total 5120K, used 0K [0x00000007bec00000, 0x00000007bf100000, 0x00000007bf100000)object space 5120K, 0% used [0x00000007bec00000,0x00000007bec00000,0x00000007bf100000)Metaspace used 2620K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576Klocalhost:newsizedemo nihui$

场景5 使用-XX:NewRatio=老年代/新生代

java -Xmx20M -Xms20M -XX:NewRatio=2 -XX:+PrintGCDetails

运行结果

localhost:newsizedemo nihui$ java -Xmx20M -Xms20M -XX:NewRatio=2 -XX:+PrintGCDetails NewSizeDemo第 0次创建完成第 1次创建完成第 2次创建完成第 3次创建完成[GC (Allocation Failure) [PSYoungGen: 4675K->512K(6144K)] 4675K->1552K(19968K), 0.0010983 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 第 4次创建完成第 5次创建完成第 6次创建完成第 7次创建完成第 8次创建完成[GC (Allocation Failure) [PSYoungGen: 5742K->512K(6144K)] 6782K->2600K(19968K), 0.0010756 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 第 9次创建完成HeapPSYoungGentotal 6144K, used 1759K [0x00000007bf980000, 0x00000007c0000000, 0x00000007c0000000)eden space 5632K, 22% used [0x00000007bf980000,0x00000007bfab7fb8,0x00000007bff00000)from space 512K, 100% used [0x00000007bff80000,0x00000007c0000000,0x00000007c0000000)to space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)ParOldGen total 13824K, used 2088K [0x00000007bec00000, 0x00000007bf980000, 0x00000007bf980000)object space 13824K, 15% used [0x00000007bec00000,0x00000007bee0a020,0x00000007bf980000)Metaspace used 2620K, capacity 4486K, committed 4864K, reserved 1056768Kclass space used 286K, capacity 386K, committed 512K, reserved 1048576Klocalhost:newsizedemo nihui$

通过上面内容的分析,可以得到一个堆内存关系图如下。(此图来自于某书)

结合这张图就可以很好的分析上面这些运行结果了。

总结

这篇分享主要是对Java虚拟机调优参数做了一定的讲解,并且演示了其中的一些参数,有兴趣的读者可以利用上面提到的-XX:PrintFlagsFinal 参数将所有的参数列表打印出来进行了解。这里就简单的说说其中比较常用的一些参数。由于现在物理机性能与JVM虚拟机性能都有一定的提高,在本地搭建测试环境的时候可以指定一些较低配置的堆内存配置与栈内存配置,这样可以有效学习一些JVM调优。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。