[alibaba/arthas]VMTools 添加内存使用排行榜公布功能

2024-04-24 928 views
6
环境信息
  • arthas-boot.jar 或者 as.sh 的版本: xxx
  • Arthas 版本: xxx
  • 操作系统版本: xxx
  • 目标进程的JVM版本: xxx
  • 执行arthas-boot的版本: xxx
重现问题的步骤
  1. xxx
  2. xxx
  3. xxx
期望的结果

正常使用的arthas排查问题的时候我们很少会去查询每个对象的内存,如果可以获取到当前占用内存最多的对象(类似于jmap的功能那个),排查问题的难度就会大大减少。然后根据内存使用排行榜,再去做具体的排查。

实际运行的结果

实际运行结果,最好有详细的日志,异常栈。尽量贴文本。

把异常信息贴到这里

回答

3

这个可以实现,不过十分消耗资源,相当于调用vmtool.getAllInstance(Object.class)获取所有实例,然后分别调用vmtool.getInstanceSize

我已经在 issues 里搜索,没有重复的issue。

环境信息

arthas-boot.jar 或者 as.sh 的版本: xxx

Arthas 版本: xxx

操作系统版本: xxx

目标进程的JVM版本: xxx

执行arthas-boot的版本: xxx

重现问题的步骤

xxx

xxx

xxx

期望的结果

正常使用的arthas排查问题的时候我们很少会去查询每个对象的内存,如果可以获取到当前占用内存最多的对象(类似于jmap的功能那个),排查问题的难度就会大大减少。然后根据内存使用排行榜,再去做具体的排查。

实际运行的结果

1

即使把实现逻辑放到jni方法中,仍然十分消耗性能。

我已经在 issues 里搜索,没有重复的issue。

环境信息

arthas-boot.jar 或者 as.sh 的版本: xxx

Arthas 版本: xxx

操作系统版本: xxx

目标进程的JVM版本: xxx

执行arthas-boot的版本: xxx

重现问题的步骤

xxx

xxx

xxx

期望的结果

正常使用的arthas排查问题的时候我们很少会去查询每个对象的内存,如果可以获取到当前占用内存最多的对象(类似于jmap的功能那个),排查问题的难度就会大大减少。然后根据内存使用排行榜,再去做具体的排查。

实际运行的结果

4

先用jmap定位占用内存最多的class,再用class定位占用内存最多的对象,如何?

我已经在 issues 里搜索,没有重复的issue。

环境信息

arthas-boot.jar 或者 as.sh 的版本: xxx

Arthas 版本: xxx

操作系统版本: xxx

目标进程的JVM版本: xxx

执行arthas-boot的版本: xxx

重现问题的步骤

xxx

xxx

xxx

期望的结果

正常使用的arthas排查问题的时候我们很少会去查询每个对象的内存,如果可以获取到当前占用内存最多的对象(类似于jmap的功能那个),排查问题的难度就会大大减少。然后根据内存使用排行榜,再去做具体的排查。

实际运行的结果

实际运行结果,最好有详细的日志,异常栈。尽量贴文本。 把异常信息贴到这里
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

8

您说的这个方法我也考虑过了。就是觉得太占资源了 。 就在思考能否将jmap histo 的功能添加到 Vmtool中。另外用jmap去获取内存大小排行的时候,是不是也是很耗内存的。

4

但是查了一天资料还没思路怎么讲jmap的 jmap histo 的功能集成到arthas 中。 也还没什么思路。。。

2

定位内存泄漏问题的时候,先通过jmap定位class,再通过class定位大对象,你觉得呢?@hengyunabc

4

定位内存泄漏问题的时候,先通过jmap定位class,再通过class定位大对象,你觉得呢?@hengyunabc

这样整定位出来的不准确,还是相当于要拿到所有实例及大小,然后计算排序。另外,jmp histo也会产生stop-the-world。

5

jmap histo 在实战中定位大内存大对象很难用,而且会 STW,线上没法用。

实际上排查内存用量大的方向,不只是定位对象大小一条:

Arthas Profiler

arthas profiler 命令。profiler start --event alloc 可追踪到代码级别的内存申请量,大部分情况下可以一次性定位到根因。

获取线程级别的内存用量

往往线程级别的用量也会看出很多问题,比如 Tomcat 线程用得少,RocketMQ 用的多,往消费 RocketMQ 的代码瞅瞅基本能知道个大概了。

线程级别内存申请:

截屏2021-08-19 下午11 00 36

GC 飙高的时候通过这个一眼就能看出大部分是消费 appPush 的线程在大量申请内存。

参考代码:

// 注意 ThreadMXBean 是 com.sun.management 不是 java.lang.management
ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();

for (long threadId : threadMXBean.getAllThreadIds()) {

  long threadAllocatedBytes = threadMXBean.getThreadAllocatedBytes(threadId);

  if (threadAllocatedBytes > 0) {

    System.out.println("thread " + threadId + ", size:" + FileUtils.byteCountToDisplaySize(threadAllocatedBytes));

  }

}