一 查看基本jvm参数
1. 查对应的进程: jps -l
2. 查看设置过值的参数:jinfo -flags pid
3. 查看初始堆内存:jinfo -flag InitialHeapSize pid
4. 查看最大堆内存:jinfo -flag MaxHeapSize pid
5. 查看永久代:jinfo -flag PermSize pid
6. 查看最大永久代:jinfo -flag MaxPermSize pid
7. 查看年轻代初始内存:jinfo -flag NewSize pid
8. 查看年轻代最大内存:jinfo -flag MaxNewSize pid
9. 查看年轻代与年老代的比值:jinfo -flag NewRatio pid
10. 查看年轻代中Eden区与Survivor区的比值:jinfo -flag SurvivorRatio pid
11. 查看分代年龄:jinfo -flag MaxTenuringThreshold pid
12. 查看收集器
12.1 查看串行收集器:jinfo -flag UseSerialGC pid
12.2 查看并行收集器:jinfo -flag UseParallelGC pid
12.3 查看并行收集器:jinfo -flag UseParNewGC pid
12.4 查看并行收集器:jinfo -flag UseParallelOldGC pid
12.5 查看CMS回收器:jinfo -flag UseConcMarkSweepGC pid
12.6 查看G1回收器:jinfo -flag UseG1GC pid
13. 查看是否打印GC日志:jinfo -flag PrintGCDetails pid
没有打印
14. 打印jvm运行配置的参数:jmap -heap pid
二 调优重要参数设置
1设置最小堆和最大堆一样
原因
空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制,空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx 相等以避免在每次GC后调整堆的大小。
操作(本机以idea作为操作)
-Xms1024m
-Xmx1024m
2 设置收集器为g1收集器
-XX:+UseG1GC
2.1 好处
-
并行性
- 回收期间,可以由多个GC线程同时工作,有效的利用多核的计算能力
-
并发性
- G1拥有与应用程序交替执行的能力,部分工作可以与应用程序同时执行,不会在整个回收期间完全阻塞应用程序。
-
分代GC
- G1兼顾了年轻代和老年代,相比较于其他的垃圾回收器,其他的收集器只能工作于年轻代或者老年代其中的一个,所以在这个方面和之前的收集器有所不同。
-
空间整理
- 在回收过程中会进行适当的对象移动,与CMS不同,只是简单的标记清理对象,在若干次GC之后,CMS必须执行一次碎片整理,G1则是每次回收都会有效的复制对象,尽量减少空间碎片。
-
可预见性
- 由于分区的原因,G1可以只选取部分区域进行内存回收,可以缩小回收范围,对于全局停顿有很好的掌控性。
2.2 概括
- JDK1.7中使用。
- 目标是为了取代CMS回收器。
- 也分为年轻代和老年代,任然是有eden区和survivor区。
- 不要求整个的eden区、年轻代或者老年代是连续的空间,使用的是一个分区算法。
2.3 案例
3 设置吞吐量大小/最大垃圾收集停顿时间
-XX:MaxGCPauseMillis=n
3.1 说明
- 设置最大垃圾收集停顿时间,如果无法满足此时间,JVM会自动调整年轻代大小(堆内存年轻代比例,eden from to 比例),以满足此在n值之内。
- 参考值:2000,具体的看业务,谨慎使用,不然服务器会崩溃
3.2 案例
4 堆占用了多少比例的时候触发GC
-XX:InitiatingHeapOccupancyPercent=n
4.1 说明
- 默认:n=45,对于这个值就触发GC
- n=当前可以使用的堆内存*100/整个Java堆
- 可以使用的堆内存占用了多少比例的时候触发GC。默认占用率是整个Java堆的45%
4.2 案例
5 设置新生代与老生代的大小比例
-XX:NewRatio=n
5.1 说明
- 设置新生代与老生代的大小比例
- 默认:2
5.2 案例
6 设置eden/survivor空间大小的比例
-XX:SurvivorRatio=n
6.1 说明
- 默认:8
6.2 案例
7 设置分代年龄
-XX:MaxTenuringThreshold=n
7.1 说明
- 默认: 15
7.2 案例
8 设置垃圾收集器在并行阶段使用的线程数
-XX:ParallelGCThreads=n
8.1 说明
- 默认值:随JVM运行的平台不同而不同
8.2 案例
9 并发垃圾收集器使用的线程数量
-XX:ConcGCThreads=n
9.1 说明
- 默认值:随JVM运行的平台不同而不同
9.2 案例
10 设置堆内存保留为假天花板的总量,以降低提升失败的可能性
-XX:G1ReservePercent=n
10.1 说明
- 默认值:10
10.2 案例
11 指定每个region区的大小
-XX:G1HeapRegionSize=n
11.1 说明
- 使用G1时Java堆会被分为大小统一的的区(region) ,该参数可以指定每个region区的大小
- 默认值:根据 heap size 算出最优解. 最小值为 1Mb, 最大值为 32Mb.
11.2 案例
三 VisualVM 工具的使用
##测试代码
public class Demo2 {
private static final int _1MB = 1 * 1024 * 1024;
public static void main(String[] args) throws InterruptedException {
int size = 1000 * 10000;
int time = 1000;
byte[] a1 = null;
for (int i = 0; i < size; ) {
System.out.println("次数:" + ++i);
a1 = new byte[_1MB];
Thread.sleep(time);
}
}
}
vm配置
-Xms10M
-Xmx10M
-XX:+UseG1GC
-XX:NewRatio=2
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=10
###1 监视(CPU,堆,类,线程)
- 正常的堆,应该是锯齿周期情况
###2 在出现OOME时生成堆
###3 内存 性能分析
- 可以查看哪些对象占用了较多的内存
- 哪些对象存活的时间比较长
###4 CPU 性能分析
###5 抽样器分析
###6 线程分析
###7 visual GC 分析(安装插件)
###8 快照功能
- 生成任意个性能分析快照并保存到本地
- 可以离线进行性能分析
Profiler 快照
应用程序快照
###9 线程转储的生成与分析
对正在运行的本地应用程序生成线程转储,把活动线程的堆栈踪迹打印出来,帮助我们了解线程运行的情况,诊断死锁、应用程序瘫痪等问题。
###10 堆转储的生成与分析
- 可以看到摘要、类、实例数等信息以及通过OQL控制台执行查询语句功能。
- 堆转储的摘要包括转储的文件大小、路径等基本信息,运行的系统环境信息,也可以显示所有的线程信息。
四 生产oom分析案例
##4.1 问题描述
项目首页,匿名无登陆,对首页进行150个线程,8小时压测,可以看到老年代一直在增加(visual gc),到某一时刻,直接oom,堆空间的图不是矩形。
##4.2 解决方案(堆dump文件分析)
- 加载dump文件
- 分析自己写的实体
- 双击进去
- 点就属性中,非基本类型的,且是自己写的实体属性(CmsUserSite)
结论
说明CmsUserSite循环引用(a–>b–>a),循环引用造成内存溢出。
dump文件地址:
链接:https://pan.baidu.com/s/1ZtDGI8C-xUjwGK1nza56DQ
提取码:67qt