目录
前言篇
实测:分别调整JVM堆大小,启动idea,jstat -GC 查看堆信息如下:
64bit-16G 电脑
S0C(kb) S1C(kb) EC(kb) OC(kb) MC(kb) 年轻代 老年代 堆大小 年轻代占比 老年代占比 年轻代Eden占比 年轻代S0占比 年轻代S1占比 设置堆大小M
3584 4096 13312 44032 33792 20.5 43 63.5 32.28% 67.72% 63.41% 17.07% 19.51% 64
12288 1536 19968 87552 33536 33 85.5 118.5 27.85% 72.15% 59.09% 36.36% 4.55% 128
10752 16896 53248 175104 34176 79 171 250 31.60% 68.40% 65.82% 13.29% 20.89% 256
21504 21504 131584 349696 34176 170.5 341.5 512 33.30% 66.70% 75.37% 12.32% 12.32% 512
43520 43520 262144 699392 33536 341 683 1024 33.30% 66.70% 75.07% 12.46% 12.46% 1024
结论:
1.新生代分区比例默认 8:2, 即 Eden:S1:S2=8:1:1, S1约定于S2
2.堆内存大小=年轻代(1/3)+老年代(2/3)
3.数据未列出S0U,S1U,实际上 S0和S1是交叉运作的, 同一时刻 S0U和S1U 肯定有一个是0
4.元空间默认大小取决于系统内存,实测 64bit-16G 电脑, 默认30M
如何调优?
1.默认先按以下比例设置JVM,来自官方文档
Xms/Xmx 一般设置为 [3-4倍] 老年代大小(系统运行一段时间后)
元空间 一般设置为 [1.2-1.5倍] 老年代大小(系统运行一段时间后)
年轻代Xmn 一般设置为 [1-1.5倍] 老年代大小(系统运行一段时间后)
老年代 一般设置为 [2-3倍] 老年代大小(系统运行一段时间后)
2.然后动态观察,是否需要调整年轻代大小和比例.
如果服务器经常卡顿,可能是因为新生代太小导致大量对象进入老年代,可调整eden比例,小于默认值8
如何解决生产事故?
1.首先查看 jmap -heap 堆信息,了解大概堆情况.
2.然后结合 jstat -GC, jstack
内存参数篇
内存参数
-Xms1024m (堆初始化内存) X-Memory Startup
-Xmx1024m (堆的最大内存) X-Memory Maximum, 注意: 堆内存大小=年轻代(1/3)+老年代(2/3)
-Xmn256m (堆-年轻代大小) X-Memory New, 注意: 老年代大小=Xmx-年轻代, 年轻代占比
-Xss256k (棧-最大深度大小) X-Stack Size
-XX:MetaspaceSize=?m (元空间默认大小) , 注意: 元空间默认大小取决于系统内存,实测64bit-16G电脑, 默认30M
-XX:MaxMetaspaceSize=?m (元空间最大大小) , 注意: 只要不设置上限,只要电脑内存足够就会动态增加
-XX:SurvivorRatio=? (默认值:8, 即新生代分区比例默认 8:2, 即 Eden:S1:S2=8:1:1, S1约定于S2)
-XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,这里使用CMS收集器)
-XX:+PrintGCDetails (打印详细的GC日志)
注意:jdk1.8已经移除了-XX:PermSize 和 -XX:MaxPermGen,取而代之的是 Metaspace
------------------------- jps 篇 -------------------------
jstack/jps 命令找不到的时候, 是因为 JDK不是用的 oracle JDK.
open jdk需要执行 yum安装
yum install java-1.8.0-openjdk-devel -y
JPS命令:
jps –l: 输出主类或者jar的完全路径名
jps –v: 输出应用基本参数
jps -l –v : 混合使用
jstack-栈信息
jstack-查看栈信息
1. 先执行 ps aux | grep java, 情况严重直接用 top,找到对应进程的 PID, 假如是:9999
2. top -Hp 9999, 查看占用资源最多的线程, 假如是 8888
3. 使用命令printf "%x\n" 8888 把线程pid转换成16进制数,得到: 22b8
4. jstack 9999 | grep -20 22b8 命令查询该线程阻塞的地方
或者直接用 jstack 9999 全局查
jmat-堆信息
jmat-查看堆信息
jmap -heap PID
查看堆内存(histogram)中的对象数量及大小
jmap -histo PID
下载整个heap使用信息:
jmap -dump:format=b,file=F:/donwload/myHeapDumpFile PID
如果只需要存活的对象信息,加上live
jmap -dump:live,format=b,file=F:/donwload/myHeapDumpFile PID
下载后的文件可以用 jvisualvm 分析
jstat-GC信息
jstat -gc PID [刷新时间ms] [刷新多少次]
显示的单位为 kb.
例如:
jstat -gc 115996 2000 1
[S0C S1C S0U S1U EC EU] [OC OU] [MC MU] [YGC YGCT FGCT FGCT GCT]
年轻代 老年代 方法区 GC次数和耗时
参数详解:
年轻代: S0C S1C S0U S1U EC EU
E,S0,S1 分别是: Eden,S1,S2区
-C 容量
-U 使用量
老年代: OC OU
方法区: MC MU
GC次数和耗时: YGC YGCT FGCT FGCT GCT
YGC、YGT: 年轻代GC次数和GC耗时
FGC、FGCT: Full GC次数和Full GC耗时
GCT: GC总耗时
jstat -gcutil PID [刷新时间ms] [刷新多少次]
显示的单位为 M
jstat -gcutil 115996 2000 1
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
24.22 0.00 99.19 54.98 95.07 93.12 32 0.062 1 0.024 0.086