JVM04——内存占用排查工具与方法

1.jps 查看系统有哪些java进程

2.jmap 查看某一时刻堆内存的占用情况

3.jconsole 多功能实时监测工具

通过下面的demo来演示堆问题诊断。

public class jvmdemo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("1....."); //输出提示,方便进行Heap Dump
        Thread.sleep(60000); //给30s时间用于Heap Dump
        byte [] arr = new byte[1024 * 1024 * 10];
        System.out.println("2.......");
        Thread.sleep(60000);
        arr = null;
        System.gc();
        System.out.println("3......");
        Thread.sleep(100000L);
    }

}

当输出1......后,先执行jps查看jvmdemo对应的pid,执行jmap -heap xxx(pid)查看此时堆内存占用情况。报错。

Error: -heap option used
Cannot connect to core dump or remote debug server. Use jhsdb jmap instead

jdk8之后的版本之前的jmap -heap xxx(pid)命令不可再使用。改用命令jhsdb jmap --heap --pid xxx.在提示信息输出后分别进行三次操作得到的结果如下。

Heap Usage:
G1 Heap:
   regions  = 2034
   capacity = 8531214336 (8136.0MB)
   used     = 0 (0.0MB)
   free     = 8531214336 (8136.0MB)
   0.0% used
G1 Young Generation:
Eden Space:
   regions  = 0
   capacity = 29360128 (28.0MB)
   used     = 0 (0.0MB)
   free     = 29360128 (28.0MB)
   0.0% used
Survivor Space:
   regions  = 0
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   0.0% used
G1 Old Generation:
   regions  = 0
   capacity = 507510784 (484.0MB)
   used     = 0 (0.0MB)
   free     = 507510784 (484.0MB)
   0.0% used
Heap Usage:
G1 Heap:
   regions  = 2034
   capacity = 8531214336 (8136.0MB)
   used     = 12582912 (12.0MB)
   free     = 8518631424 (8124.0MB)
   0.14749262536873156% used
G1 Young Generation:
Eden Space:
   regions  = 0
   capacity = 29360128 (28.0MB)
   used     = 0 (0.0MB)
   free     = 29360128 (28.0MB)
   0.0% used
Survivor Space:
   regions  = 0
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   0.0% used
G1 Old Generation:
   regions  = 3
   capacity = 507510784 (484.0MB)
   used     = 12582912 (12.0MB)
   free     = 494927872 (472.0MB)
   2.479338842975207% used
Heap Usage:
G1 Heap:
   regions  = 2034
   capacity = 8531214336 (8136.0MB)
   used     = 673872 (0.6426544189453125MB)
   free     = 8530540464 (8135.357345581055MB)
   0.007898898954588403% used
G1 Young Generation:
Eden Space:
   regions  = 0
   capacity = 8388608 (8.0MB)
   used     = 0 (0.0MB)
   free     = 8388608 (8.0MB)
   0.0% used
Survivor Space:
   regions  = 0
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   0.0% used
G1 Old Generation:
   regions  = 1
   capacity = 8388608 (8.0MB)
   used     = 673872 (0.6426544189453125MB)
   free     = 7714736 (7.3573455810546875MB)
   8.033180236816406% used

重点查看uesd这一项,这里JVM version 是16.0.2+7-67,不同版本可能略有差异。

使用jconsole可以实时观测数据。

图片说明

案例:多次垃圾回收后内存占用仍然很高。

jvisualvm也是一个可视化工具,比jconsole更好用。在高版本JDK(大于1.8或后期更新的1.8版本)中已经不会再自动集成它了。参考博客可以下载独立版:JDK 高版本没有VisualVM_东理羁客的博客-CSDN博客

现在使用jvisualvm执行GC,但是内存并没有减少很多。

图片说明

进行Heap Dump,按照占用内存大小对class进行排序。

图片说明

发现是byte[]类的锅,占了210M内存。点进去。发现byte[]的实例数特别多(13675),导致其内存占用特别大(210M)。还可以看到,这个byte[]字段被Student类的对象所引用,变量名为big。

图片说明

然后定位到对应的源码。

/**
 * 演示查看对象个数 堆转储 dump
 */
public class Demo4_1 {

    public static void main(String[] args) throws InterruptedException {
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < 200; i++) {
            students.add(new Student());
//            Student student = new Student();
        }
        Thread.sleep(1000000000L);
    }
}
class Student {
    private byte[] big = new byte[1024*1024];
}

果然,我们有200个Student对象,持有了内存占用1M的big实例200个。

java全栈日日学 文章被收录于专栏

java全栈每日必学,不要高估自己一年能做的事,不要低估自己十年能做的事

全部评论

相关推荐

会不会进去就面临裁员啊....
MellowWW:我朋友签的美区销售岗,这才是天崩开局
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务