JVM手动调优的完整过程(包含cpu飙升、OOM问题定位等详细步骤)三

本文详细介绍了JVM调优中针对CPU飙升和OOM问题的定位方法。通过实战案例,展示了如何使用arthas工具分析高CPU使用率线程,发现并修复死循环问题。同时,讲解了程序发生OOM后,如何利用jvisualvm分析dump文件以定位问题。
摘要由CSDN通过智能技术生成

因为第二部分内容过于冗长,为了避免引起阅读反感,所以后续案例将在此部分补充!

三、jvm调优(后续)

实战案例分析、定位cpu飙升、OOM问题

(3)案例三,测试代码如下:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class T15_FullGC_Problem03 {
    public static Map<String,String> allJurisdictionMap() {
        Map<String,String> map = new HashMap();
        map.put("1","权限1");
        map.put("2","权限2");
        map.put("3","权限3");
        map.put("4","权限4");
        return map;
    }


    public static void main(String[] args) {
        //模拟登陆人信息
        Map<String,String> personCodeMap = new HashMap<>();
        getPersonJurisdictionMap(T15_FullGC_Problem03.allJurisdictionMap(),personCodeMap);
    }

    /**
     * 返回登陆人对应的权限信息
     * @param allJurisdictionMap
     * @param personCodeMap
     * @return
     */
    private static Map<String,String> getPersonJurisdictionMap(Map<String,String> allJurisdictionMap,Map<String,String> personCodeMap){
        Map<String,String> map2 = new HashMap(allJurisdictionMap);
        Iterator<String> iterator = map2.keySet().iterator();
        while (iterator.hasNext()){
            for (String key : personCodeMap.keySet()){
                if (iterator.next().equals(key)){
                    personCodeMap.put(key,map2.get(key));
                }
            }
        }
        return personCodeMap;
    }

}

其主要功能就是根据公司的全部权限信息,筛选出当前登陆人的信息!
javac 编译后运行程序,使用top命令观察状态:
在这里插入图片描述
可以看到cpu已经100%了,通过arthas工具attach此进程,并使用thread命令观察:
在这里插入图片描述
发现线程1的cup使用率已经高达99%,然后我们接着使用thread命令:thread 1 (数字表示线程id),定位此线程的栈信息:
在这里插入图片描述
通过以上信息我们发现问题出在:getPersonJurisdictionMap方法!

下面我们来分析这段问题代码!
(1)由于传入方法的personCodeMap集合为空,所以导致for循环的代码块不会被执行;
(2)iterator.hasNext()方法不会使迭代器的指针发生偏移,所以最终发生了死循环;

下面是优化后的代码:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class T15_FullGC_Problem03 {
    public static Map<String,String> allJurisdictionMap() {
        Map<String,String> map = new HashMap();
        map.put("1","权限1");
        map.put("2","权限2");
        map.put("3","权限3");
        map.put("4","权限4");
        return map;
    }


    public static void main(String[] args) {
        //模拟登陆人信息
        Map<String,String> personCodeMap = new HashMap<>();
        getPersonJurisdictionMap(T15_FullGC_Problem03.allJurisdictionMap(),personCodeMap);
    }

    /**
     * 返回登陆人对应的权限信息
     * @param allJurisdictionMap
     * @param personCodeMap
     * @return
     */
    private static Map<String,String> getPersonJurisdictionMap(Map<String,String> allJurisdictionMap,Map<String,String> personCodeMap){
        Map<String,String> map2 = new HashMap(allJurisdictionMap);
        Iterator<String> iterator = map2.keySet().iterator();
        while (iterator.hasNext()){
            String param = iterator.next();
            for (String key : personCodeMap.keySet()){
                if (param.equals(key)){
                    personCodeMap.put(key,map2.get(key));
                }
            }
        }
        return personCodeMap;
    }

}

代码分析:
这里我们在每次迭代的时候直接获取元素 String param = iterator.next(); ,然后进行比较!这样即使personCodeMap为空,在每次迭代时iterator.next()都会使指针发生偏移!因此不会发生死循环!

(4)前面的案例都是在cpu升高(程序没死之前),没有发生OOM时的定位方法,当程序发生OOM死亡后,我们如何根据此次的OOM信息定位问题呢!

java -Xms200M -Xmx200M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/taosun/logs/ -Xloggc:/opt/taosun/logs/tao-sun-gc-%t.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCCause T15_FullGC_Problem01

根据程序启动时指定的OOM 的log目录,查看本次日志信息:
在这里插入图片描述
hprof结尾的文件都是OOM时产生的dump文件(案例一OOM时的log文件,我这里运行的次数比较多),下载对应的文件,使用jdk自带的jvisualvm工具进行dump文件的分析!

1.选择文件----》装入
在这里插入图片描述

2.找到自己下载的文件目录,文件类型选择堆Dump,点击打开倒入文件!
在这里插入图片描述

3.文件装载完成后,将会显示如下基本信息、线程信息等!
在这里插入图片描述

4.选择后面的类信息,即可查看本次oom所产生的实例对象信息
在这里插入图片描述

左边是对象实例名称,右边是对象实例数、大小等信息!

此处的信息和我们使用jmap命令时一样,所以这里就不再做分析了!

ok!至此jvm调优相关的内容已经全部结束!如对您有帮助,转载时请标明出处!谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值