前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM优化系列-------[4丶jmap的使用以及内存溢出分析]

JVM优化系列-------[4丶jmap的使用以及内存溢出分析]

作者头像
框架师
发布2019-10-15 15:01:38
9650
发布2019-10-15 15:01:38
举报
文章被收录于专栏:墨白的Java基地墨白的Java基地

正文

引言

前面几章内容我们学习了JVM的内存回收和JVM参数等系列,今天墨白给大家分享的是jmap的使用以及内存溢出分析等详情,话不多说,正文开始;

昨天我们通过jstat可以对JVM堆的内存进行统计分析,而jmap可以获取到更加详细的内容,如:内存使用情况的汇总、对内存溢出的定位与分析。

在写这篇文章的时候我发现了一个问题,新版的Linux系统加入了 ptrace-scope 机制. 这种机制为了防止用户访问当前正在运行的进程的内存和状态, 而一些调试软件本身就是利用 ptrace 来进行获取某进程的内存状态的(包括GDB),所以在新版本的Linux系统, 默认情况下不允许再访问了,所以我们无法使用之前的jmap -heap这个命令了,今天我们用-clstats这个命令来查看JVM内存分析;

先查看下jmap的命令:

    Example: jmap -dump:live,format=b,file=heap.bin 
[root@localhost ~]# jmap -h
Usage:
== 连接到运行进程并打印类加载器统计信息
    jmap -clstats 
        to connect to running process and print class loader statistics
== 连接到正在运行的进程并打印有关等待完成的对象的信息
    jmap -finalizerinfo 
        to connect to running process and print information on objects awaiting finalization
== 连接到运行进程并打印Java对象堆的直方图  
    jmap -histo[:live] 
        to connect to running process and print histogram of java object heap
        if the "live" suboption is specified, only count live objects
== 连接到正在运行的进程并转储Java堆
    jmap -dump: 
        to connect to running process and dump java heap
    dump-options:
      live         dump only live objects; if not specified,
                   all objects in the heap are dumped.
      format=b     binary format
      file=  dump heap to 
    Example: jmap -dump:live,format=b,file=heap.bin 
  • 查看内存使用情况我们就用-clstats这个命令
== 连接到运行进程并打印类加载器统计信息
[root@localhost bin]# jmap -clstats 30685
==================================省略3600条信息=================================
         0        536          56    3584           9       449      2304    2024     4768     6792 websocket.snake.SnakeAnnotation
             13578248    2340680       15712 7693904       40079   1987618  11822808 7659360 15423064 23082424 Total
                58.8%      10.1%        0.1%   33.3%           -      8.6%     51.2%   33.2%    66.8%   100.0%
Index Super InstBytes KlassBytes annotations   CpAll MethodCount Bytecodes MethodAll   ROAll    RWAll    Total ClassName

细心找找我们发现它有几个关键字,如下

  • Configuration:堆内存配置信息
  • Usage:堆内存的使用情况
  • PS Young Generation :年轻代
  • PS Old Generation :年老代

查看内存中对象数量及大小,如下:

 1== 查看所有对象,包括活跃以及非活跃的
 2[root@localhost ~]# jmap -histo 30685 | more
 3 num     #instances         #bytes  class name (module)
 4-------------------------------------------------------
 5   1:         60386        5335640  [B (java.base@9.0.4)
 6   2:          1220        3146456  [C (java.base@9.0.4)
 7   3:         42784        1026816  java.lang.String (java.base@9.0.4)
 8   4:         19972         639104  java.util.HashMap$Node (java.base@9.0.4)
 9   5:          5436         627008  [I (java.base@9.0.4)
10   6:          3824         462160  java.lang.Class (java.base@9.0.4)
11===============================忽略内容=======================================
12  41:           632          25280  java.util.LinkedHashMap$Entry (java.base@9.0.4)

对象说明:

== 对象说明
B byte
C char
D double
F float
I int
J long
Z boolean
[ 数组,如[I表示int[]
[L+类名 其他对象
  • 我们还可以将内存使用情况dump到文件中:

有些时候我们需要将jvm当前内存中的情况dump到文件中,然后对它进行分析,jmap也是支持dump到文件中的,如下。

==  将内存使用的详细情况输出到文件
[root@localhost test]#  jmap -dump:format=b,file=m.dat 30685 
Heap dump file created
[root@localhost test]# ll
总用量 31752
drwxr-xr-x. 2 root root        6 10月 11 00:25 aaa
== 可以看到新建了一个m.dat的文件
-rw-------. 1 root root 32505476 10月 11 00:30 m.dat
-rw-r--r--. 1 root root      575 10月  8 23:58 TestJVM.class
-rw-r--r--. 1 root root      225 10月  8 23:58 TestJVM.java
  • 通过jhat对dump文件进行分析;

我们将jvm的内存dump到文件中,这个文件是一个二进制的文件,不方便查看,这时我们可以借助于jhat工具进行查看。需要注意一点的是,Java9版本之后就没有jhat命令了;

== 通过jhat对dump文件进行分析
[root@node01 test]# jhat ‐port 9999 m.dat
Reading from /test/m.dat...
Dump file created Mon Sep 10 01:04:21 CST 2018
Snapshot read, resolving...
Resolving 204094 objects...
Chasing references, expect 40
dots........................................
Eliminating duplicate references........................................
Snapshot resolved.
Started HTTP server on port 9999
Server is ready.

打开浏览器进行访问:

打开浏览器进行访问:http://访问IP:9999/

这里面的内容就是jhat做的解析内容,可以看到它打包方式有一些是数组,如数组的对象有那些内容,还可以看到打包是以Javax.el方式又有一些,还有servlet等方式,它会以一些包的方式自动给我们分类,这些方法也可以点击进去查看详情.包括实例等等有很多内容,这里就不一一说了,感兴趣的小伙伴可以看一下,最后面还给我们提供了OQL查询功能;

这个功能类似SQL语句,下面我们看下是怎么使用的,它有给我们提供API,点击QQL Help就可以查看它的使用文档了;

现在我们自己来玩一下这个功能,查询一个字符串大于100的内容有哪些;

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 框架师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档