JVM参数

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

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

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

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

BTW:

 

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

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

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

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

 

方式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 将当前的存活对象dump到文件,此时会触发FullGC

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

 

以我司的一个RPC服务为例。

BTW:刚上线的新服务,不知道该设置多大的内存的时候,可以先多设置一点内存,然后根据GC之后的情况来进行分析。

初始JVM内存参数设置为: Xmx=2G Xms=2G xmn=1G

 

使用jstat 查看当前的GC情况。如下图:

在这里插入图片描述

YGC平均耗时: 173.825s/15799=11ms

FGC平均耗时:0.817s/41=19.9ms

平均大约10-20s会产生一次YGC

 

看起来似乎不错,YGC触发的频率不高,FGC的耗时也不高,但这样的内存设置是不是有些浪费呢?

为了快速看数据,我们使用了方式2,产生了几次FullGC,FullGC之后,使用的jmap -heap 来看的当前的堆内存情况

相关文章

jinfo 命令可以用来查看 Java 进程运行的 JVM 参数,命令如下...
原文链接:https://www.cnblogs.com/niejunlei/p/5987611.ht...
java 语言, 开发者不能直接控制程序运行内存, 对象的创建都是...
jvm
1.jvm的简单抽象模型:  2.类加载机制     双亲委派模...
堆外内存JVM启动时分配的内存,称为堆内存,与之相对的,在代...
1.springboot和tomcat2.springcloud的请求如何通过网关鉴权?...