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

news/2024/7/24 9:28:19

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

 

问题:
新上线一个java服务,或者是RPC或者是WEB站点, 内存的设置该怎么设置呢?设置成多大比较合适,既不浪费内存,又不影响性能呢?

分析:
依据的原则是根据Java Performance里面的推荐公式来进行设置。

 
296d1509689688.png

具体来讲:
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

具体操作实例:
以我司的一个RPC服务为例。
BTW:刚上线的新服务,不知道该设置多大的内存的时候,可以先多设置一点内存,然后根据GC之后的情况来进行分析。
初始JVM内存参数设置为: Xmx=2G Xms=2G xmn=1G

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

 
23b61509689687.png

YGC平均耗时: 173.825s/15799=11ms
FGC平均耗时:0.817s/41=19.9ms
平均大约10-20s会产生一次YGC

看起来似乎不错,YGC触发的频率不高,FGC的耗时也不高,但这样的内存设置是不是有些浪费呢?
为了快速看数据,我们使用了方式2,产生了几次FullGC,FullGC之后,使用的jmap -heap 来看的当前的堆内存情况(也可以根据GC日志来看)
heap情况如下图:(命令 : jmap -heap <pid>)

 
f9c71509689687.png

上图中的concurrent mark-sweep generation即为老年代的内存描述。
老年代的内存占用为100M左右。 按照整个堆大小是老年代(FullGC)之后的3-4倍计算的话,设置各代的内存情况如下:
Xmx=512m Xms=512m Xmn=128m PermSize=128m 老年代的大小为 (512-128=384m)为老年代存活对象大小的3倍左右
调整之后的,heap情况

 
aaaaa689686.png

GC情况如下:

 
bbbbb689686.png

YGC 差不多在10s左右触发一次。每次YGC平均耗时大约9.41ms。可接受。
FGC平均耗时:0.016s/2=8ms
整体的GC耗时减少。但GC频率比之前的2G时的要多了一些。

注: 看上述GC的时候,发现YGC的次数突然会增多很多个,比如 从1359次到了1364次。具体原因是?

总结:
在内存相对紧张的情况下,可以按照上述的方式来进行内存的调优, 找到一个在GC频率和GC耗时上都可接受的一个内存设置,可以用较小的内存满足当前的服务需要
但当内存相对宽裕的时候,可以相对给服务多增加一点内存,可以减少GC的频率,GC的耗时相应会增加一些。 一般要求低延时的可以考虑多设置一点内存, 对延时要求不高的,可以按照上述方式设置较小内存。

补充:
永久代(方法区)并不在堆内,所以之前有看过一篇文章中描述的 整个堆大小=年轻代+年老代+永久代的描述是不正确的。

转自:

https://blog.csdn.net/losetowin/article/details/78569001

补充

-verbose:gc 现实垃圾收集信息
-Xloggc:gc.log 指定垃圾收集日志文件
-Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一
-XX:SurvivorRatio=2 :生还者池的大小,默认是2,如果垃圾回收变成了瓶颈,您可以尝试定制生成池设置

-XX:NewSize: 新生成的池的初始大小。 缺省值为2M。
-XX:MaxNewSize: 新生成的池的最大大小。 缺省值为32M。

+XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。
-Xss:每个线程的Stack大小,“-Xss 15120” 这使得JBoss每增加一个线程(thread)就会立即消耗15M内存,而最佳值应该是128K,默认值好像是512k.

转载于:https://www.cnblogs.com/zhangfengshi/p/11343102.html


http://www.niftyadmin.cn/n/1499623.html

相关文章

阿里云提示Discuz uc.key泄露导致代码注入漏洞uc.php的解决方法

适用所有用UC整合 阿里云提示漏洞&#xff1a; discuz中的/api/uc.php存在代码写入漏洞,导致黑客可写入恶意代码获取uckey,.......... 漏洞名称&#xff1a;Discuz uc.key泄露导致代码注入漏洞 补丁文件&#xff1a;/api/uc.php补丁来源&#xff1a;云盾自研 解决方法&#xff…

Intellij IDEA 14中使用MyBatis-generator 自动生成MyBatis代码

一&#xff1a;项目建立好及其基本的测试好 二&#xff1a;在maven项目的pom.xml 添加mybatis-generator-maven-plugin 插件 <build><finalName>CourseDesignManage</finalName><plugins><plugin><groupId>org.mybatis.generator</grou…

redis使用watch完成秒杀抢购功能

Redis使用watch完成秒杀抢购功能&#xff1a;使用redis中两个key完成秒杀抢购功能&#xff0c;mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表。它的优点如下&#xff1a;1. 首先选用内存数据库来抢购速度极快。2. 速度快并发自然没不是问题。3. 使用悲观锁&#xf…

CSS之BFC(Block Formatting Context)

这是我的第一篇博客&#xff0c;不知道从什么开始写起&#xff0c;那就从我现在看的开始写起吧。 以前我也不知道BFC是什么&#xff0c;今天看了才知道原来以前经常接触&#xff0c;只是不知道专业名称罢了。就像闭包、继承一样&#xff0c;以前经常用到&#xff0c;只是不知道…

个人博客练手项目

最近比较闲&#xff0c;学了一些杂七杂八的技术&#xff0c;但不知道怎么用&#xff0c;想的是做一个简单的博客项目来练手&#xff0c;不知道能不能坚持下去&#xff0c;现在把项目框架搭建好了 项目技术选择 后端&#xff1a;nodeexpressmongoose前端&#xff1a;vue2vue-rou…

服务器端渲染基础

服务器端渲染基础概念什么是渲染传统的服务端渲染通过Node.js演示传统的服务器端渲染模式客户端渲染现代化的服务端渲染服务端渲染使用建议概念 随着前端技术栈和工具链的迭代成熟,前端工程化,模块化成为了当下主流技术方案,在这比技术浪潮中,涌现了诸如Anfular,React,Vue等基…

支持动态滑出效果的vue-dynamic-dialog的使用说明

使用说明 安装 npm i vue-dynamic-dialog -D 复制代码在 main.js 中写入以下内容&#xff1a; import Vue from vue import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css import App from ./App.vue import VueDynamicDialog from vue-dynamic-dial…

Nuxt.js基础

Nuxt.js基础Nuxt.js介绍初始化Nuxt.js初始化Nuxt.js应用的方式案例代码分支说明路由-基础路由实例路由导航a链接导航nuxt-link导航组件编程式导航动态路由嵌套路由路由配置视图模板布局默认布局组件自定义布局组件异步数据-asyncDataNuxt.js异步数据-asyncData方法asyncData方法…