jvm 生产项目优化

    技术2022-07-10  205

    一 查看基本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,对于这个值就触发GCn=当前可以使用的堆内存*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

    五 开发配置

    1本地配置

    -Xmx1g -Xms1g -Xmn900m -XX:+UseG1GC -Xloggc:gc.log -XX:+PrintGCDetails

    2 linux tomcat 配置

    进入tomcat的bin目录

    修改catalina.sh文件

    if [ -z "$JSSE_OPTS" ] ; then JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048" fi JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS" JVM_OPTS=" -Xmx2g -Xms2g -Xmn700m -XX:+UseG1GC -Xloggc:/home/hd/tomcat-app-node01/logs/gc.log -XX:+PrintGCDetails " MYPERF4J_OPTS=" -javaagent:/home/hd/myPerf4J/MyPerf4J-ASM.jar -DMyPerf4JPropFile=/home/hd/myPerf4J/myPerf4J.properties" JAVA_OPTS="$JAVA_OPTS $JVM_OPTS $MYPERF4J_OPTS" # Register custom URL handlers # Do this here so custom URL handles (specifically 'war:...') can be used in the security policy JAVA_OPTS="$JAVA_OPTS -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"
    Processed: 0.052, SQL: 9