说明:转载本人掘金文章 https://juejin.cn/post/7094613544687108126
内存分配
查看内存分配情况
1.查看堆总内存 jinfo -flag MaxHeapSize vmid
2.查看新生代内存 jinfo -flag NewSize vmid
3.查看老年代内存 jinfo -flag OldSize vmid
4.查看使用的垃圾收集器 jinfo -flags vmid
5.查看元空间(方法区)内存 jinfo -flag MetaspaceSize(MaxMetaspaceSize) vmid
设置内存
1.设置堆最小大小 java -jar -Xms2g xxx.jar
2.设置堆最大大小 java -jar -Xmx2g xxx.jar (建议最大最小内存设置一样)
3.设置新生代大小 java -jar -XX:NewSize=500m xxx.jar(根据实际情况设置,没特别要求使用默认1/3堆内存即可 )
4.设置新生代老年代内存比例 java -jar -XX:NewRatio=3 xxx.jar(默认是2,这个和-XX:NewSize一样,只是一个是比例,一个是实际大小,建议调整比例)
5.设置新生代内存内部eden和survivor比例 java -jar -XX:SurvivorRatio=6 xxx.jar(默认是8,eden区占新生区内存8/10,survivor占2个1/10 )
5.设置垃圾收集器 java -jar -XX:+UseParallelGC xxx.jar(不同垃圾回收器不一样,G1是设置region大小)
6.设置元空间大小 java -jar -XX:MaxMetaspaceSize=500m (也就是方法区大小,存放常量池和类信息)
说明:一般实际情况设置-Xms和-Xmx设置一样即可,然后如果有需要,设置新生代大小,一般web程序取决于并发量。
查看内存使用情况
jstat -gc -h10(多少行重新打印头) vmid 1000(间隔时间ms) 100(打印次数)
说明:笔者参数 -Xms2g -Xmx2g -XX:+UseParallelGC -XX:NewRatio=1(2g内存大小,使用para回收器,年轻代和老年代1:1)
S0C:survivor0分配空间大小kb
S1C:survivor1分配空间大小kb
S0U:survivor0使用空间大小kb
S1U:survivor1使用空间大小kb
EC:eden分配空间大小kb大小kb
EU:eden使用空间大小kb大小kb
OC:老年代分配空间大小kb
OU:老年代使用空间大小kb
MC:方法区分配空间大小kb
MU:方法区使用空间大小kb
YGC:年轻代gc次数大小kb
YGCT:年轻代gc使用时间大小kb
FGC:老年代gc次数大小kb
FGCT:老年代gc使用时间大小kb
说明:
1.关注EU使用情况,一般并发高的代码,很快就会占满
2.和EU关联的就是YGC,看看回收频率,不要太高,会发生stw占用时间长,特别是c端
3.MC主要是元空间大小,一般使用动态代理,会频繁产生新类,会对这个空间有影响
内存方案推荐(web && spring)
1.新生代和老年代比例,推荐1:1 (我们web程序新生代空间分配很重要,没次接口请求完成,对象基本上就没用了,特别是并发量高的情况下,一次就用完可能性很大,直接就gc了。老年代其实只是存储spring需要的对象常驻内存,或者有些缓存直接存在jvm,还是不建议,太占用老年代了,其实老年代使用内存不大)
2.元空间大小其实基本固定,测试环境观察类信息和常量池使用的大小即可,考虑到大量动态代理使用,生成代理类情况,可以设置大一点,一般给个500m足够
3.新生代的eden和survivor使用默认的 8:1:1即可,web程序survivor还是数据量挺小的,还是不建议用jvm缓存,否则对survivor和老年代都不太友好,最好用第三方缓存中间件
4.上述提供了思路,实际根据上面思路具体分配