橘子学JVM之命令行监控04之jmap

jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。开发人员可以在控制台中输入命令“jmap -help”查阅jmap工具的具体使用方式和一些标准选项配置。
他的不同的功能都是通过-option这个参数的不同来区分指定的。

官方帮助文档:https://docs.oracle.com/en/java/javase/11/tools/jmap.html

基本使用语法为:
● jmap [option] pid
● jmap [option] executable core
● jmap [option] [server_id@] remote server IP or hostname

导出的dump文件可以显示当前的jvm空间的对象分布情况,可以帮助我们分析这类关于对象文件的一个情况。
在这里插入图片描述
说明:这些参数和linux下输入显示的命令多少会有不同,包括也受jdk版本的影响。

一、导出堆文件 -dump

1、手动导出

导出dump文件是jmap最重要的作用之一,Heap Dump称之为堆存储文件,指的是一个java进程在某个时间点的内存对象的快照,那一瞬间的捕捉。Heap Dump在触发内存快照的时候会保存的此刻的信息如下。
1、全部的对象
2、全部的类信息
3、gc roots的信息
4、线程栈和本地变量的数据
以上四种数据会被那一瞬间捕捉到。
说明一下:、
1、通常在写Heap Dump文件前会触发一个full GC,所以heap dump里面保存的都是full gc后留下的对象的信息。
2、由于生产dump文件比较耗时,因此需要耐心等待,尤其是大内存的时候镜像生成dump文件需要耗费更长的时间完成。

语法

> jmap -dump:format=b,file=<filename.hprof> <pid>
> jmap -dump:live,format=b,file=<filename.hprof> <pid>

开一个程序

/**
 * @author: levi
 * @description: -Xms60m -Xmx60m -XX:SurvivorRatio=8  堆空间初始和最大值设置为60m,s区和eden区的比例为8:1:1
 * @date: 2022-10-3 20:10
 * @version: 1.0
 */
public class GCtest {
    // 100KB大小
    static final int _100KB = 1024 * 100;
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            // 每120毫秒就添加100KB进这个集合里面
            byte[] arr = new byte[_100KB];
            list.add(arr);
            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

查看jps找到线程id为136888
我们使用jmap来操作生成一下dump文件。

# 我们连续导出两个dump文件
jmap -dump:format=b,file=D:1.hprof  136888
Dumping heap to D:\1.hprof ...
Heap dump file created

jmap -dump:format=b,file=D:2.hprof  136888
Dumping heap to D:\2.hprof ...
Heap dump file created

# 然后使用live标签导出一个名字为3的dump文件
jmap -dump:live,format=b,file=D:3.hprof  136888
Dumping heap to D:\3.hprof ...
Heap dump file created

我们来解释一下这个命令
jmap -dump:format=b,file=D:1.hprof 136888
-dump表示就是导出堆文件的参数。
format=b.file表示我们导出这个文件的格式是标准格式,后面能用那些工具打开。
file=D:1.hprof 表示导出位置在D盘下面,名字为1,格式是hprof。
136888就是这个程序的进程id。

jmap -dump:live,format=b,file=D:3.hprof 136888
其余的一样,就是加了一个live标签,表示我们导出的是当前快照里面只有存活对象,回收的不导出了。上面那种是整个堆都导出,包括回收的和存活的对象。
有时候我们生产使用的时候,一般有存活的就行了,因为已经回收的不影响了,有问题都是那些没法回收的对象导致的。这样只导出存活的文件大小还能小点。
此时你每次执行这个命令都能导出对应的文件了。
但是这个hprof文件是二进制的,你得用工具看。文本打开看的就是乱码。

由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。

举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。

另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。与前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。

2、自动导出

自动导出的意思就是你不用管,只要你配置好参数,等到他堆溢出了,自己会按照你得配置生成指定的文件。
只需要我们配置两个东西

-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=d:\\5.hprof

第一个就是配置堆内存溢出的时候自动导出,第二行就是配置自动导出时候的hprof文件的位置。
等到溢出了就会生成该文件。

配置参数为:
-Xms60m
-Xmx60m
-XX:SurvivorRatio=8
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=d:\\5.hprof
public class GCtest {
    // 100KB大小
    static final int _100KB = 1024 * 100;
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            // 每120毫秒就添加100KB进这个集合里面
            byte[] arr = new byte[_100KB];
            list.add(arr);
            try {
                Thread.sleep(6);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

等到溢出的时候我们看一下D盘:
在这里插入图片描述

二、显示堆内存相关信息

我们先运行那段程序,然后jps查看出线程id为8960.

我们执行jmap -heap 8960 > d:1.txt
jmap -histo 8960 > d:2.txt
我们为了方便查看把结果导出到txt文件里面。

我们程序运行的jvm参数为:-Xms60m -Xmx60m -XX:SurvivorRatio=8

1、-heap

我们查看一下-heap的结果为:

Attaching to process ID 8836, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.181-b13

using thread-local object allocation.
Parallel GC with 8 thread(s)
# 下面就是堆内存大小的显式,和我们在jvm参数中配置的是一样的。
Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 62914560 (60.0MB)
   NewSize                  = 20971520 (20.0MB)
   MaxNewSize               = 20971520 (20.0MB)
   OldSize                  = 41943040 (40.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)
# 下面是我导出那一瞬间的时候当前的jvm内存里面的占用情况
Heap Usage:
PS Young Generation
Eden Space:
   capacity = 16777216 (16.0MB)
   used     = 6128432 (5.8445281982421875MB)
   free     = 10648784 (10.155471801757812MB)
   36.52830123901367% used
From Space:
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
To Space:
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
PS Old Generation
   capacity = 41943040 (40.0MB)
   used     = 31067936 (29.628692626953125MB)
   free     = 10875104 (10.371307373046875MB)
   74.07173156738281% used

1734 interned Strings occupying 156752 bytes.

2、-histo

我们查看一下-histo的结果为:
下面我们看到的他是你当前导出那一瞬间的空间的占用情况,比如类名,对象实例的大小,按从大到小排列的,我们可以据此查看一下空间里面有哪些大对象。


 num     #instances         #bytes  class name
----------------------------------------------
   1:           358       33413272  [B
   2:          2518         329744  [C
   3:           603          69048  java.lang.Class
   4:          2373          56952  java.lang.String
   5:           605          36296  [Ljava.lang.Object;
   6:           791          31640  java.util.TreeMap$Entry
   7:           115          25032  [I
   8:           197           8056  [Ljava.lang.String;
   9:            79           5688  java.lang.reflect.Field
  10:            85           5440  java.net.URL
  11:           152           4864  java.util.Hashtable$Entry
  12:           137           4384  java.util.concurrent.ConcurrentHashMap$Node
  13:            11           4136  java.lang.Thread
  14:           256           4096  java.lang.Integer
  15:            99           3960  java.lang.ref.SoftReference
  16:           100           3200  java.util.HashMap$Node
  17:            42           2352  sun.misc.URLClassPath$JarLoader
  18:            19           1968  [Ljava.util.HashMap$Node;
  19:           123           1968  java.lang.Object
  20:            46           1840  java.util.LinkedHashMap$Entry
  21:            38           1824  sun.util.locale.LocaleObjectCache$CacheEntry
  22:            21           1680  [Ljava.util.WeakHashMap$Entry;
  23:            18           1440  java.lang.reflect.Constructor
  24:             5           1424  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  25:            16           1408  java.lang.reflect.Method
  26:             8           1264  [Ljava.util.Hashtable$Entry;
  27:            13           1248  java.util.jar.JarFile$JarFileEntry
  28:            31           1240  java.lang.ref.Finalizer
  29:            25           1200  java.util.HashMap
  30:            21           1176  sun.nio.cs.UTF_8$Encoder
  31:            18           1152  java.util.jar.JarFile
  32:            46           1104  java.io.ExpiringCache$Entry
  33:             2           1064  [Ljava.lang.invoke.MethodHandle;
  34:            19           1064  java.lang.Class$ReflectionData
  35:             1           1040  [Ljava.lang.Integer;
  36:             1           1040  [[C
  37:            26           1040  java.io.ObjectStreamField
  38:            21           1008  java.util.WeakHashMap
  39:            27            864  com.intellij.rt.debugger.agent.CaptureAgent$InstrumentPoint
  40:            26            832  java.lang.ref.ReferenceQueue
  41:            19            760  sun.util.locale.BaseLocale$Key
  42:            29            696  java.util.ArrayList
  43:             8            640  [S
  44:            19            608  java.util.Locale
  45:            19            608  sun.util.locale.BaseLocale
  46:            15            600  java.security.AccessControlContext
  47:            15            600  sun.nio.cs.UTF_8$Decoder
  48:            27            584  [Ljava.lang.Class;
  49:            18            576  java.util.zip.ZipCoder
  50:             8            512  java.util.concurrent.ConcurrentHashMap
  51:            20            480  java.util.jar.Attributes$Name
  52:             8            456  [Ljava.lang.reflect.Field;
  53:            19            456  java.util.Locale$LocaleKey
  54:            28            448  java.lang.ref.ReferenceQueue$Lock
  55:            18            432  java.util.ArrayDeque
  56:            13            416  java.io.File
  57:             1            384  java.lang.ref.Finalizer$FinalizerThread
  58:             6            384  java.nio.DirectByteBuffer
  59:             8            384  java.util.zip.Inflater
  60:             1            376  java.lang.ref.Reference$ReferenceHandler
  61:             6            336  java.nio.DirectLongBufferU
  62:            10            320  java.lang.OutOfMemoryError
  63:            10            288  [Ljava.io.ObjectStreamField;
  64:            12            288  sun.misc.MetaIndex
  65:             6            240  java.util.WeakHashMap$Entry
  66:             9            216  [Ljava.lang.reflect.Constructor;
  67:             9            216  sun.reflect.NativeConstructorAccessorImpl
  68:             4            192  java.util.Hashtable
  69:             4            192  java.util.Properties
  70:             4            192  java.util.TreeMap
  71:             6            192  java.util.Vector
  72:             8            192  java.util.zip.ZStreamRef
  73:             3            168  java.lang.Package
  74:             4            160  java.security.ProtectionDomain
  75:             6            144  java.util.LinkedList$Node
  76:             2            144  java.util.regex.Pattern
  77:             6            144  sun.misc.PerfCounter
  78:             9            144  sun.reflect.DelegatingConstructorAccessorImpl
  79:             6            144  sun.security.util.DisabledAlgorithmConstraints$Constraint$Operator
  80:             2            128  java.io.ExpiringCache$1
  81:             4            128  java.security.CodeSource
  82:             4            128  java.util.LinkedList
  83:             3            120  java.io.FileDescriptor
  84:             2             96  [Ljava.lang.reflect.Method;
  85:             4             96  java.lang.RuntimePermission
  86:             2             96  java.lang.ThreadGroup
  87:             3             96  java.lang.ThreadLocal$ThreadLocalMap$Entry
  88:             2             96  java.nio.HeapByteBuffer
  89:             3             96  java.nio.file.attribute.FileTime
  90:             3             96  java.util.Stack
  91:             1             96  sun.misc.Launcher$AppClassLoader
  92:             2             96  sun.misc.URLClassPath
  93:             2             96  sun.nio.cs.StreamEncoder
  94:             1             88  sun.misc.Launcher$ExtClassLoader
  95:             1             80  [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
  96:             2             80  java.io.BufferedWriter
  97:             2             80  java.io.ExpiringCache
  98:             2             80  java.lang.ClassLoader$NativeLibrary
  99:             5             80  java.lang.ThreadLocal
 100:             2             80  sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
 101:             3             72  java.util.Collections$SynchronizedSet
 102:             3             72  java.util.concurrent.atomic.AtomicLong
 103:             2             64  [Ljava.lang.Thread;
 104:             4             64  [Ljava.security.Principal;
 105:             2             64  java.io.FileOutputStream
 106:             2             64  java.io.FilePermission
 107:             2             64  java.io.PrintStream
 108:             2             64  java.lang.ClassValue$Entry
 109:             2             64  java.lang.VirtualMachineError
 110:             2             64  java.lang.ref.ReferenceQueue$Null
 111:             2             64  java.security.BasicPermissionCollection
 112:             2             64  java.security.Permissions
 113:             4             64  java.security.ProtectionDomain$Key
 114:             1             56  sun.nio.cs.ext.DoubleByte$Decoder
 115:             1             48  [J
 116:             1             48  [Ljava.util.concurrent.TimeUnit;
 117:             2             48  java.io.BufferedOutputStream
 118:             2             48  java.io.File$PathStatus
 119:             2             48  java.io.FilePermissionCollection
 120:             2             48  java.io.OutputStreamWriter
 121:             2             48  java.nio.charset.CoderResult
 122:             3             48  java.nio.charset.CodingErrorAction
 123:             2             48  java.util.regex.Pattern$SliceI
 124:             2             48  java.util.regex.Pattern$Start
 125:             2             48  sun.instrument.TransformerManager
 126:             2             48  sun.misc.NativeSignalHandler
 127:             2             48  sun.misc.Signal
 128:             2             48  sun.security.util.DisabledAlgorithmConstraints$DisabledConstraint
 129:             2             40  [Lsun.instrument.TransformerManager$TransformerInfo;
 130:             1             40  [Lsun.security.util.DisabledAlgorithmConstraints$Constraint$Operator;
 131:             1             40  java.io.BufferedInputStream
 132:             1             40  sun.nio.cs.StandardCharsets$Aliases
 133:             1             40  sun.nio.cs.StandardCharsets$Cache
 134:             1             40  sun.nio.cs.StandardCharsets$Classes
 135:             1             40  sun.nio.cs.ext.ExtendedCharsets
 136:             1             32  [Ljava.lang.OutOfMemoryError;
 137:             2             32  [Ljava.lang.StackTraceElement;
 138:             1             32  [Ljava.lang.ThreadGroup;
 139:             2             32  com.intellij.rt.debugger.agent.CaptureAgent$ParamKeyProvider
 140:             1             32  java.io.FileInputStream
 141:             1             32  java.io.WinNTFileSystem
 142:             1             32  java.lang.ArithmeticException
 143:             2             32  java.lang.Boolean
 144:             1             32  java.lang.NullPointerException
 145:             1             32  java.lang.StringCoding$StringDecoder
 146:             1             32  java.lang.StringCoding$StringEncoder
 147:             2             32  java.nio.ByteOrder
 148:             2             32  java.util.HashSet
 149:             2             32  java.util.concurrent.atomic.AtomicInteger
 150:             1             32  java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
 151:             1             32  java.util.regex.Pattern$Branch
 152:             1             32  sun.instrument.InstrumentationImpl
 153:             2             32  sun.net.www.protocol.jar.Handler
 154:             1             32  sun.nio.cs.StandardCharsets
 155:             1             24  [Ljava.io.File$PathStatus;
 156:             1             24  [Ljava.lang.ClassValue$Entry;
 157:             1             24  [Ljava.util.regex.Pattern$Node;
 158:             1             24  [Lsun.launcher.LauncherHelper;
 159:             1             24  com.intellij.rt.debugger.agent.CaptureAgent$FieldKeyProvider
 160:             1             24  java.lang.ClassValue$Version
 161:             1             24  java.lang.StringBuilder
 162:             1             24  java.lang.ThreadLocal$ThreadLocalMap
 163:             1             24  java.lang.invoke.MethodHandleImpl$4
 164:             1             24  java.lang.reflect.ReflectPermission
 165:             1             24  java.util.BitSet
 166:             1             24  java.util.Collections$EmptyMap
 167:             1             24  java.util.Collections$SetFromMap
 168:             1             24  java.util.Collections$UnmodifiableRandomAccessList
 169:             1             24  java.util.Locale$Cache
 170:             1             24  java.util.concurrent.TimeUnit$1
 171:             1             24  java.util.concurrent.TimeUnit$2
 172:             1             24  java.util.concurrent.TimeUnit$3
 173:             1             24  java.util.concurrent.TimeUnit$4
 174:             1             24  java.util.concurrent.TimeUnit$5
 175:             1             24  java.util.concurrent.TimeUnit$6
 176:             1             24  java.util.concurrent.TimeUnit$7
 177:             1             24  java.util.jar.Manifest
 178:             1             24  java.util.regex.Pattern$Single
 179:             1             24  sun.instrument.TransformerManager$TransformerInfo
 180:             1             24  sun.launcher.LauncherHelper
 181:             1             24  sun.misc.JarIndex
 182:             1             24  sun.misc.URLClassPath$FileLoader
 183:             1             24  sun.nio.cs.ISO_8859_1
 184:             1             24  sun.nio.cs.ThreadLocalCoders$1
 185:             1             24  sun.nio.cs.ThreadLocalCoders$2
 186:             1             24  sun.nio.cs.US_ASCII
 187:             1             24  sun.nio.cs.UTF_16
 188:             1             24  sun.nio.cs.UTF_16BE
 189:             1             24  sun.nio.cs.UTF_16LE
 190:             1             24  sun.nio.cs.UTF_8
 191:             1             24  sun.nio.cs.ext.GBK
 192:             1             24  sun.reflect.NativeMethodAccessorImpl
 193:             1             24  sun.security.util.DisabledAlgorithmConstraints
 194:             1             24  sun.util.locale.BaseLocale$Cache
 195:             1             16  [Ljava.lang.Throwable;
 196:             1             16  [Ljava.security.cert.Certificate;
 197:             1             16  com.intellij.rt.debugger.agent.CaptureAgent$1
 198:             1             16  com.intellij.rt.debugger.agent.CaptureAgent$CaptureTransformer
 199:             1             16  com.intellij.rt.debugger.agent.CaptureStorage$1
 200:             1             16  java.io.FileDescriptor$1
 201:             1             16  java.lang.CharacterDataLatin1
 202:             1             16  java.lang.ClassValue$Identity
 203:             1             16  java.lang.Runtime
 204:             1             16  java.lang.String$CaseInsensitiveComparator
 205:             1             16  java.lang.System$2
 206:             1             16  java.lang.Terminator$1
 207:             1             16  java.lang.invoke.MemberName$Factory
 208:             1             16  java.lang.invoke.MethodHandleImpl$2
 209:             1             16  java.lang.invoke.MethodHandleImpl$3
 210:             1             16  java.lang.ref.Reference$1
 211:             1             16  java.lang.ref.Reference$Lock
 212:             1             16  java.lang.reflect.ReflectAccess
 213:             1             16  java.net.URLClassLoader$7
 214:             1             16  java.nio.Bits$1
 215:             1             16  java.nio.charset.CoderResult$1
 216:             1             16  java.nio.charset.CoderResult$2
 217:             1             16  java.security.ProtectionDomain$2
 218:             1             16  java.security.ProtectionDomain$JavaSecurityAccessImpl
 219:             1             16  java.util.Collections$EmptyList
 220:             1             16  java.util.Collections$EmptySet
 221:             1             16  java.util.Hashtable$EntrySet
 222:             1             16  java.util.WeakHashMap$KeySet
 223:             1             16  java.util.concurrent.atomic.AtomicBoolean
 224:             1             16  java.util.jar.Attributes
 225:             1             16  java.util.jar.JavaUtilJarAccessImpl
 226:             1             16  java.util.regex.Pattern$4
 227:             1             16  java.util.regex.Pattern$BranchConn
 228:             1             16  java.util.regex.Pattern$LastNode
 229:             1             16  java.util.regex.Pattern$Node
 230:             1             16  java.util.zip.ZipFile$1
 231:             1             16  sun.misc.ASCIICaseInsensitiveComparator
 232:             1             16  sun.misc.Launcher
 233:             1             16  sun.misc.Launcher$Factory
 234:             1             16  sun.misc.Perf
 235:             1             16  sun.misc.Unsafe
 236:             1             16  sun.net.www.protocol.file.Handler
 237:             1             16  sun.reflect.DelegatingMethodAccessorImpl
 238:             1             16  sun.reflect.ReflectionFactory
 239:             1             16  sun.security.util.AlgorithmDecomposer
 240:             1             16  sun.security.util.DisabledAlgorithmConstraints$Constraints
Total          9747       34058552

但是我们上面说的jmap都是基于那一瞬间的值,不是连续的。这就是一个弊端。

3、其他指令

jamp -permstat pid查看系统的ClassLoader的信息
jmap -finalizerinfo 查看堆积在finalizer队列中的对象。
这两个在win下面不能运行。需要在linux系统运行。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值