推荐一个我从小用到大的排查JVM内存神器,真爽

本文介绍了Arthas,一个强大的Java开发和在线调试工具,涵盖了JVM监控、线程分析、数据观测、类加载管理、反编译、代码替换以及面试技巧等内容,帮助开发者高效解决问题和优化性能。
摘要由CSDN通过智能技术生成

| — | — |

| jvm | 查看当前JVM信息 |

| thread | 查看当前JVM的线程堆栈信息 |

| watch | 方法执行数据观测 |

| dashboard | 当前系统的实时数据面板 |

| trace | 方法内部调用路径,并输出方法路径上的每个节点上耗时 |

| stack | 输出当前方法被调用的调用路径 |

| tt | 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测 |

| vmoption | 查看,更新JVM已加载的类信息 |

| sc | 查看JVM已加载的类信息 |

| sm | 查看已加载类的方法信息 |

| jad | 反编译指定已加载类的源码 |

| classloader | 查看classloader的继承树,urls,类加载信息 |

| heapdump | 类似jmap命令的heap dump 功能 |

jvm

OPERATING-SYSTEM:系统相关参数

THREAD相关:

  • COUNT : JVM当前活跃的线程数

  • DAEMON-COUNT : JVM当前活跃的守护线程数

  • PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数

  • STARTED-COUNT: 从JVM启动开始总共启动过的线程次数

  • DEADLOCK-COUNT: JVM当前死锁的线程数

MEMORY

FILE-DESCRIPTOR(文件描述符相关):

  • MAX-FILE-DESCRIPTOR-COUNT:JVM进程最大可以打开的文件描述符数

  • OPEN-FILE-DESCRIPTOR-COUNT:JVM当前打开的文件描述符数

thread 命令

参数说明:

| 命令 | 详细说明 |

| — | — |

| id | 线程id |

| [n:] | 指定最忙的前N个线程并打印堆栈 |

| [b] | 找出当前阻塞其他线程的线程 |

| [i] | 指定cpu使用率统计的采样间隔,单位为毫秒,默认值为200 |

| [–all] | 显示所有匹配的线程 |

打印当前最忙的N个线程并打印堆栈

thread -n 3

thread 查看所有线程

thread 17: 显示指定线程的运行堆栈

thread -i: 指定采样时间间隔

thread -i 1000 : 统计最近1000ms内的线程CPU时间。

thread -n 3 -i 1000 : 列出1000ms内最忙的3个线程栈

dashboard 命令

运行程序时,会显示当前程序的实时信息,如qps, rt, 错误数, 线程池信息等等

数据说明:

  • ID: Java级别的线程ID

  • NAME: 线程名

  • GROUP: 线程组名

  • PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高

  • STATE: 线程的状态CPU%: 线程的cpu使用率。比如采样间隔1000ms,某个线程的增量cpu时间为100ms,则cpu使用率=100/1000=10%

  • DELTA_TIME: 上次采样之后线程运行增量CPU时间,数据格式为秒

  • TIME: 线程运行总CPU时间,数据格式为分:秒

  • INTERRUPTED: 线程当前的中断位状态

  • DAEMON: 是否是daemon线程

参数说明:

| 参数名称 | 详细说明 |

| — | — |

| id | 刷新实时数据的时间间隔 (ms),默认5000ms |

| [n:] | 刷新实时数据的次数 |

sc 命令

查看JVM已加载的类信息,通过SC我们可以看到我们这个类的详细信息,包括是从哪个jar包读取的,他是不是接口/枚举类等,甚至包括他是从哪个类加载器加载的。

参数说明:

| 参数名称 | 详细说明 |

| — | — |

| class-pattern | 类名表达式匹配 |

| method-pattern | 方法名表达式匹配 |

| [d] | 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。如果一个类被多个ClassLoader所加载,则会出现多次 |

| [E] | 开启正则表达式匹配,默认为通配符匹配 |

sc -d *CardInfo: 打印类的详细信息

sc -d -f *CardInfo:打印类的Fiedld信息

heapdump + jhat分析

heapdump:类似于jmap命令

创建到指定文件夹下:

[arthas@365564]$ heapdump /usr/local/mxn/dump.hprof

Dumping heap to /usr/local/mxn/dump.hprof …

Heap dump file created

创建成功后,我们就可以在指定文件夹下看到对应的dump文件,然后使用命令jhat dump.hprof,生成文件,成功后我们就可以通过IP+端口进行访问了

访问:

然后我们就可以通过IP+端口去访问它了,里面有个他的other,我们拉到最底下,找

Show instance counts for all classes (including platform)

从下面我们可以分析出来哪个类包含的对象最多,分析出来哪个类产生的对象

这个里面最强大的功能还是叫做 Execute Object Query Language (OQL) query,这个里面可以显示有哪些对象,对象有多少个字节和引用,可以观察到哪个对象产生了问题,如下图所示,显示所有String对应的对象

搜索点进去之后我们还能看到这个对象到底占用了多少个字节,有多少个引用指向了这个Object,这个OQL的语法也是很灵活,我们可以使用where条件去过滤

jad

jad:反编译某个类,或者反编译某个类的某个方法,动态代理生成类的问题定位 第三方的类(观察代码) 版本问题(确定自己最新提交的版本是不是被使用)

有人可能会问这个有啥用,源码我不是自己就知道吗?因为有时我们经常会不确定线上或者测试环境的包是否是我们修改过的,这时候就可以通过jad反编译来看下,是否是最新的代码

redafine

redafine:热替换,动态更新代码,不用重启jvm目前有些限制条件:只能改方法实现(方法已经运行完成),不能改方法名, 不能改属性 m() -> mm()

比如我们在线上环境有个class确认有问题,想要重新替换,一般情况下只能停掉服务器重新发布,在普通的小公司这样是可以的,但是在大规模公司京东淘宝这样的是不能停的,因为整个流程是非常复杂的,那怎么办呢?大家可以看到下面的案例

首先我们新建一个测试案例:

public class T{

public static void main(String[] args) throws Exception{

for(;😉{

System.in.read();

new TT().m();

}

}

}

public class TT{

public void m(){

System.out.println(2);

}

}

使用命令javac *.java,编译成class文件,然后运行 T 文件

[root@VM-0-7-centos t]# java T

a

2

2

当我们输入a的时候打印2,但是我们上线以后才发现,我们需要输出的1,这个是如果要从本地更改要重新发布上线,为了这一个修改,明显是不值当的,但是如果我们用 redafine 热部署就可以帮助我们直接替换,不用重新发布jvm

然后我们将 T 这个程序挂靠到 Arthas 上面去

然后我们直接修改 TT.java 程序 vi TT.java,将里面打印2的值修改成1

public class TT{

public void m(){

System.out.println(1);

}

}

然后编译执行 ```javac TT.java ````

在回到我们挂靠的Arthas 上面执行 redefine /usr/local/mxn/fuccGc/t/TT.class

[arthas@398842]$ redefine /usr/local/mxn/fuccGc/t/TT.class

redefine success, size: 1, classes:

TT

执行成功

大家可以看到我们在没有重新启动的情况下成功替换了class文件

watch

watch:方法执行的数据观测,可以通过watch指令,来监控某个类,监控后,运行下你的功能,复现下场景,arthas会提供给你具体的出参和入参,帮助你排查故障

trace

输出方法调用路径,并输出耗时,这个指令对于优化代码非常的有用,可以看出具体每个方法执行的时间,如果是for循环等重复语句,还能看出n次循环中的最大耗时,最小耗时,和平均耗时,完美!

tt

在我们对某个方法开启tt后,会记录每一次调用(我们可以设置最大监控次数)的入参和返回参数,并能对这些不同时间下调进行观测

[arthas@405136]$ tt -t FullGCTest modelFit

命令参数解析-t

tt 命令有很多个主参数,-t 就是其中之一。这个参数的表明希望记录下类 *Test 的 print 方法的每次执行情况。

-n 3

当你执行一个调用量不高的方法时可能你还能有足够的时间用 CTRL+C 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。

此时你可以通过 -n 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断tt命令的记录过程,避免人工操作无法停止的情况。

ognl表达式

ognl表达式

OGNL特殊用法请参考:https://github.com/alibaba/arthas/issues/71

OGNL表达式官方指南:https://commons.apache.org/proper/commons-ognl/language-guide.html

调用静态函数:ognl '@java.lang.System@out.println("hello")'

获取静态类的静态字段:ognl '@FullGCTest@random'

Arthas还支持Web Console,详见:https://alibaba.github.io/arthas/web-console.html

总结

Arthas是一个线上Debug神器,相比于其他工具,Arthas有着比较全面的功能,上手也比较容易,对于刚开始入门的小伙伴也是可以轻松掌握的,对于文中有不懂或者有问题的小伙伴,大家可以在下面留言评论。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

在这里插入图片描述

在这里插入图片描述

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

[外链图片转存中…(img-Bxg6rAfy-1713704897310)]

[外链图片转存中…(img-uRNeSP3F-1713704897310)]

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值