创建成功后,我们就可以在指定文件夹下看到对应的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条件去过滤
jadjad:反编译某个类,或者反编译某个类的某个方法,动态代理生成类的问题定位 第三方的类(观察代码) 版本问题(确定自己最新提交的版本是不是被使用)
有人可能会问这个有啥用,源码我不是自己就知道吗?因为有时我们经常会不确定线上或者测试环境的包是否是我们修改过的,这时候就可以通过jad反编译来看下,是否是最新的代码
redafineredafine:热替换,动态更新代码,不用重启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文件