JVM学习七

JVM调优案例1—风险评控

一般是运维团队首先收到报警信息(CPU飙升 Memory占用高)

/**
 * 从数据库中读取信用数据,套用模型,并把结果进行记录和传输
 */

public class T15_FullGC_Problem01 {

    private static class CardInfo {
        BigDecimal price = new BigDecimal(0.0);
        String name = "张三";
        int age = 5;
        Date birthdate = new Date();

        public void m() {

        }
    }

    private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50,
            new ThreadPoolExecutor.DiscardOldestPolicy());

    public static void main(String[] args) throws Exception {
        executor.setMaximumPoolSize(50);

        for (;;){
            modelFit();
            Thread.sleep(100);
        }
    }

    private static void modelFit(){
        List<CardInfo> taskList = getAllCardInfo();
        taskList.forEach(info -> {
            // do something
            executor.scheduleWithFixedDelay(() -> {
                //do sth with info
                info.m();

            }, 2, 3, TimeUnit.SECONDS);
        });
    }

    private static List<CardInfo> getAllCardInfo(){
        List<CardInfo> taskList = new ArrayList<>();

        for (int i = 0; i < 100; i++) {
            CardInfo ci = new CardInfo();
            taskList.add(ci);
        }

        return taskList;
    }
}

让这个程序在我的虚拟机上面跑起来
在这里插入图片描述

在这里插入图片描述
跑到后面就发现在频繁的fullGC但是FullGC回收的内存小只又小,再看我们调用的ScheduledThreadPool,我们只设置了核心线程数,最大线程数,一个拒绝策略,并没有去设置它的阻塞队列的大小,然而这个阻塞队列的最大值为Integer的MaxValue然后再放那么多的对象进去,又没有给他回收,所以就会导致频繁的FullGC,但是FullGC后它的内存并没有被回收多少。
在这里插入图片描述

分析CPU及内存占用情况方式

可以通过top命令查看CPU及内存占用情况:
top命令观察到问题:内存不断增长 CPU占用率居高不下
在这里插入图片描述
同时也可以通过top -Hp查看java进程里面的各个线程的占用:
top -Hp 观察进程中的线程,哪个线程CPU和内存占比高
在这里插入图片描述
再来看jstack命令,输入线程id:

在这里插入图片描述
通过jstack 加上java程序的进程号可以获得当前java进程里面的线程信息:
需中点关注:WAITING BLOCKED
例如:
找到持有这把锁的线程:
waiting on <0x0000000088ca3310> (a java.lang.Object)
假如有一个进程中100个线程,很多线程都在waiting on ,一定要找到是哪个线程持有这把锁
怎么找?搜索jstack dump的信息,找 ,看哪个线程持有这把锁RUNNABLE【死锁问题解决】
在这里插入图片描述
为什么阿里规范里规定,线程的名称(尤其是线程池)都要写有意义的名称
怎么样自定义线程池里的线程名称?(自定义ThreadFactory)

jinfo命令

在这里插入图片描述
jstat各种区域占用的大小(不直观)

在这里插入图片描述
jconsole远程连接:
在本地的jdk文件目录的bin目录下面有个jconsole
在这里插入图片描述
在这里插入图片描述

java -Djava.rmi.server.hostname=192.168.75.133 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=11111 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -XX:+PrintGC -Xms200M -Xmx200M T15_FullGC_Problem01
在这里插入图片描述
在这里插入图片描述
jvisual远程连接:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上就可以看到是ScheduledThreadPoolExecutor造成了OOM,但是一般不会用这个图形化界面,因为这个服务一直在影响原来的主进程。
jprofiler(要钱)一般公司不用。
1、已经上线的系统不用图形界面用什么?(cmdline arthas)
2、图形界面到底用在什么地方?测试!测试的时候进行监控(上线前压测观察)

查找有多少个对象产生:
在这里插入图片描述
jmap -histo 对性能影响较小
如上图的第二种方式:由于Jmap -dump比较影响性能,可以先将当前服务器给隔离然后再通过Jmap去查看信息。

在这里插入图片描述

Arthas

文档参考链接:
https://github.com/alibaba/arthas/blob/master/README_CN.md
运行刚才的风险评控程序发现JVM垃圾回收器的FullGC每次都只会回收一点点。
通过Arthas来分析一下原因:
输入java -jar命令启动arthas,并输入1可以看到arhtas被挂载到42998的进程上面了
在这里插入图片描述
输入help就能看到athas的命令了:

在这里插入图片描述
arthas的JVM命令介绍:相当于jinfo,查看JVM的详细配置信息:
包含了一些JVM的基础信息
在这里插入图片描述
也包含了垃圾收集器算法的信息:
在这里插入图片描述
还有thread命令,查看线程的相关信息

在这里插入图片描述
查看线程状态:
在这里插入图片描述
输入dashboard命令类似于top命令:
在这里插入图片描述
在这里插入图片描述
还有heapdump相当于jmap导出堆信息:
对系统性能会有影响
在这里插入图片描述

dump文件分析

jhat命令分析heapdump的文件
在这里插入图片描述
如上启动了一个server:
在这里插入图片描述
找到instance counts for All Classes,类似于一个jmap分析的结果:

在这里插入图片描述
在这里插入图片描述
使用OQL工具查找特定对象的问题:
在这里插入图片描述
可以通过查看哪些对象出了问题:
在这里插入图片描述
在这里插入图片描述

arthas的反编译和热替换

jad反编译

作用:
1、动态代理生成类的问题定位
2、第三方的类(观察代码)
3、版本问题(确定自己最新提交的版本是不是被使用)
在这里插入图片描述

redefine热替换

在这里插入图片描述
在这里插入图片描述
编译运行程序:

在这里插入图片描述
此时输出的是1,然后再用arthas监控,redefine
在这里插入图片描述
然后再vi TT.java,直接改
在这里插入图片描述
然后再javac TT.java
在这里插入图片描述
然后再在arthas处redifine:
在这里插入图片描述
然后再在输入窗口那里输入a此时输出2:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值