JVM参数汇总:JVM内存设置多大合适?Xmx和Xmn如何设置

本文详细介绍了JVM启动参数的分类,重点关注了内存设置,尤其是Xmx和Xmn参数的调整。Xmx定义了Java堆的最大大小,Xmn则是年轻代的大小。建议年轻代大小为老年代存活对象的1-1.5倍,而整个堆大小设置为3-4倍。确定老年代存活对象大小的方法包括分析GC日志和使用jmap工具。正确设置这些参数有助于优化JVM性能,降低FullGC的频率,提高应用响应速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、java启动参数共分为三类:

其一是标准参数(-), 所有的JVM实现都必须实现这些参数的功能,而且向后兼容; 其二是非标准参数(-X), 默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容; 其三是非Stable参数(-XX),此类参数各个jvm实现会有所不同,这些都是不稳定的并且不推荐在生产环境中使用。将来可能会随时取消,需要慎重使用;上都被实现),而且如果在新版本有什么改动也不会发布通知。 对响应时间要求很高的系统来说,良好掌握JVM关于GC调优的参数是很重要的。比如一个高流量地延迟的电子交易平台,他要求的响应时间都是毫秒级的。要获得适合的参数组合需要大量的分析和不断的尝试,更依赖于交易系统的特性。

关于JVM选项的几点: 1) 布尔型参数选项:-XX:+ 打开, -XX:- 关闭。(比如-XX:+PrintGCDetails) 2) 数字型参数选项通过-XX:=设定。数字可以是m/M(兆字节),k/K(千字节),g/G(G字节)。 比如:32K表示32768字节。(比如-XX:HeapDumpPath=./java_pid.hprof) 3) 字符行参数选项通过-XX:=设定,通常用来指定一个文件,路径,或者一个命令列表。(比如-XX:+PrintGCDetails) 命令 java -help可以列出java 应用启动时标准选项(不同的JVM实现是不同的)。 java -X可以列出不标准的参数(这是JVM的扩展特性)。-X相关的选项不是标准的,被改变也不会通知。 如果你想查看当前应用使用的JVM参数,你可以使用:ManagementFactory.getRuntimeMXBean().getInputArguments()。

二、标准参数中比较有用的:

verbose -verbose:class 输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断。

-verbose:gc 输出每次GC的相关情况。

-verbose:jni 输出native方法调用的相关情况,一般用于诊断jni调用错误信息。

命令查看java的class字节码文件、verbose、synchronize

三、非标准参数又称为扩展参数

JVM内存设置多大合适?Xmx和Xmn如何设置?

具体具体来讲:参照 老年代存活对象大小

Java整个堆大小设置,Xmx 和 Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍

永久代 PermSize和MaxPermSize设置为老年代存活对象的1.2-1.5倍。

年轻代Xmn的设置为老年代存活对象的1-1.5倍。

老年代的内存大小设置为老年代存活对象的2-3倍。

BTW:

1、Sun官方建议年轻代的大小为整个堆的3/8左右, 所以按照上述设置的方式,基本符合Sun的建议。

2、堆大小=年轻代大小+年老代大小, 即xmx=xmn+老年代大小 。 Permsize不影响堆大小。

3、为什么要按照上面的来进行设置呢? 没有具体的说明,但应该是根据多种调优之后得出的一个结论。

如何确认老年代存活对象大小?

方式1(推荐/比较稳妥):

JVM参数中添加GC日志,GC日志中会记录每次FullGC之后各代的内存大小,观察老年代GC之后的空间大小。可观察一段时间内(比如2天)的FullGC之后的内存情况,根据多次的FullGC之后的老年代的空间大小数据来预估FullGC之后老年代的存活对象大小(可根据多次FullGC之后的内存大小取平均值)

方式2:(强制触发FullGC, 会影响线上服务,慎用)

方式1的方式比较可行,但需要更改JVM参数,并分析日志。同时,在使用CMS回收器的时候,有可能不能触发FullGC(只发生CMS GC),所以日志中并没有记录FullGC的日志。在分析的时候就比较难处理。

BTW:使用jstat -gcutil工具来看FullGC的时候, CMS GC是会造成2次的FullGC次数增加。 具体可参见之前写的一篇关于jstat使用的文章

所以,有时候需要强制触发一次FullGC,来观察FullGC之后的老年代存活对象大小。

注:强制触发FullGC,会造成线上服务停顿(STW),要谨慎,建议的操作方式为,在强制FullGC前先把服务节点摘除,FullGC之后再将服务挂回可用节点,对外提供服务

在不同时间段触发FullGC,根据多次FullGC之后的老年代内存情况来预估FullGC之后的老年代存活对象大小

如何触发FullGC ?

使用jmap工具可触发FullGC

jmap -dump:live,format=b,file=heap.bin <pid> 将当前的存活对象dump到文件,此时会触发FullGC

jmap -histo:live <pid> 打印每个class的实例数目,内存占用,类全名信息.live子参数加上后,只统计活的对象数量. 此时会触发FullGC

链接:[#link]( https://www.dutycode.com/m/?post=153 )

非标准化的参数在将来的版本中可能会改变。所有的这类参数都以-X开始,并且可以用java -X来检索。注意,不能保证所有参数都可以被检索出来,其中就没有-Xcomp。例如:

常用的参数介绍:

-Xms512m 设置JVM促使内存为512m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 -Xmx512m ,设置JVM最大可用内存为512M。 -Xmn200m:设置年轻代大小为200M。此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是(eden+1 survivor space)不同的。

计算公式有:

年老代大小=-Xmx减去-Xmn

整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。

持久代一般固定大小为64m,所以增大年轻代(-Xmn)后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8

-XX:SurvivorRatio

用于设置Eden和其中一个Survivor的比值,默认比例为8(Eden):1(一个survivor),这个值也比较重要。

例如:XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6。

-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。 -Xloggc:file 与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。 若与verbose命令同时出现在命令行中,则以-Xloggc为准。 -Xprof 跟踪正运行的程序,并将跟踪数据在标准输出输出;适合于开发环境调试。

-Xrunhprof

-Xdebug:JVM调试参数,用于远程调试

例如在tomcat中的远程调试设置方法为-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000

-Xboot

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值