一、基本情况

jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。

开发人员可以在控制台中输入命令“jmap -help”查阅jmap工具的具体使用方式和一些标准选项配置。

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

二、基本语法

它的基本使用语法为:

  • jmap [option]
  • jmap [option]
  • jmap [option] [server_id@]

其中option包括:
image.png
说明:这些参数和linux下输入显示的命令多少会有不同,包括也受jdk版本的影响。

2.1、-dump

生成Java堆转储快照: dump文件
特别的: -dump:live只保存堆中的存活对象
可以从dump文件中分析出那些对象导致了堆或非堆的溢出

2.2、-heap

输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等

2.3、-histo

输出堆中对象的统计信息,包括类、实例数量和合计容量
特别的: -histo:live只统计堆中的存活对象

2.4、-permstat

以ClassLoader为统计口径输出永久代的内存状态信息
仅linux/solaris平台有效

2.5、-finalizerinfo

显示在F-Queue中等待Finalizer线程执行finalize方法的对象
仅linux/solaris平台有效

2.6、-F

当虚拟机进程对-dump选项没有任何响应时,可使用此选项强制执行生成dump文件
仅linux/solaris平台有效

2.7、-h | -help

jmap工具使用的帮助命令

2.8、-J

传递参数给jmap启动的jvm

三、使用1:导出内存映像文件

一般来说,使用jmap指令生成dump文件的操作算得上是最常用的jmap命令之一,将堆中所有存活对象导出至一个文件之中。
Heap Dump又叫做堆存储文件,指一个Java进程在某个时间点的内存快照。Heap Dump在触发内存快照的时候会保存此刻的信息如下:

  • All Objects

Class,fields,primitive values and references.

  • All Classes

ClassLoader,name , super class,static fields

  • Garbage Collection Roots

0bjects defined to be reachable by the JVM

  • Thread Stacks and Local Variables

The call-stacks of threads at the moment of the snapshot,and per-frameinformation about local objects

说明:
1.通常在写Heap Dump文件前会触发一次Full Gc,所以heap dump文件里保存的都是Ful1GC后留下的对象信息。
2.由于生成dump文件比较耗时,因此大家需要耐心等待,尤其是大内存镜像生成dump文件则需要耗费更长的时间来完成。

3.1、手动的方式

jmap -dump:format=b,file=
jmap -dump:live,format=b,file=
其中format=b是将jmap生成的hprof文件能被图形界面工具识别
-dump:live打印存活的对象
jmap -dump:live,format=b,file=F:\weblogicdump\dump.hprof 9376
image.png
image.png
请使用JProfiler工具打开dump文件

3.2、自动的方式

当程序发生OOM退出系统时,一些瞬时信息都随着程序的终止而消失,而重现OOM问题往往比较困难或者耗时。此时若能在OOM时,自动导出dump文件就显得非常迫切。
这里介绍一种比较常用的取得堆快照文件的方法,即使用:
-XX:+HeapDumpOnOutOfMemoryError: 在程序发生OOM时,导出应用程序的当前堆快照。
-XX:HeapDumpPath: 可以指定堆快照的保存位置。

比如:
-Xmx100m -XX:+HeapDumpOnOutOfMemoryError -XX:+HeapDumpPath=D:\dump\m.hprof

指令:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=

image.png
-Xms60m -Xmx60m -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump5.hprof

四、使用2:显示堆内存相关信息

4.1、jmap -heap pid

image.png
a.txt文件内容如下:

  1. Attaching to process ID 3076, please wait...
  2. Debugger attached successfully.
  3. Server compiler detected.
  4. JVM version is 25.291-b10
  5. using thread-local object allocation.
  6. Parallel GC with 8 thread(s)
  7. Heap Configuration:
  8. MinHeapFreeRatio = 0
  9. MaxHeapFreeRatio = 100
  10. MaxHeapSize = 62914560 (60.0MB)//堆空间
  11. NewSize = 20971520 (20.0MB)//新生代
  12. MaxNewSize = 20971520 (20.0MB)//新生代
  13. OldSize = 41943040 (40.0MB)//老年代
  14. NewRatio = 2
  15. SurvivorRatio = 8
  16. MetaspaceSize = 21807104 (20.796875MB)//元空间大小
  17. CompressedClassSpaceSize = 1073741824 (1024.0MB)
  18. MaxMetaspaceSize = 17592186044415 MB
  19. G1HeapRegionSize = 0 (0.0MB)
  20. Heap Usage:
  21. PS Young Generation
  22. Eden Space:
  23. capacity = 16777216 (16.0MB)
  24. used = 7799040 (7.437744140625MB)
  25. free = 8978176 (8.562255859375MB)
  26. 46.48590087890625% used
  27. From Space:
  28. capacity = 2097152 (2.0MB)
  29. used = 2076896 (1.980682373046875MB)
  30. free = 20256 (0.019317626953125MB)
  31. 99.03411865234375% used
  32. To Space:
  33. capacity = 2097152 (2.0MB)
  34. used = 0 (0.0MB)
  35. free = 2097152 (2.0MB)
  36. 0.0% used
  37. PS Old Generation
  38. capacity = 41943040 (40.0MB)
  39. used = 11857992 (11.308662414550781MB)
  40. free = 30085048 (28.69133758544922MB)
  41. 28.271656036376953% used
  42. 3174 interned Strings occupying 260464 bytes.

linux环境下
image.png

4.2、-jmap -histo pid

image.png
b.txt文件内容如下:


 num     #instances         #bytes  class name
----------------------------------------------
   1:          1037       55953232  [B
   2:          5047         512872  [C
   3:          4898         117552  java.lang.String
   4:           706          80880  java.lang.Class
   5:           708          50864  [Ljava.lang.Object;
   6:           791          31640  java.util.TreeMap$Entry
   7:           136          21400  [I
   8:           239          15296  java.net.URL
   9:           470          15040  java.util.HashMap$Node
  10:           267          12640  [Ljava.lang.String;
  11:            79           7584  java.util.jar.JarFile$JarFileEntry
  12:            91           7280  [Ljava.util.WeakHashMap$Entry;
  13:           170           6800  java.lang.ref.Finalizer
  14:           118           6608  sun.misc.URLClassPath$JarLoader
  15:            28           6464  [Ljava.util.HashMap$Node;
  16:            88           5632  java.util.jar.JarFile
  17:            90           5040  sun.nio.cs.UTF_8$Encoder
  18:           120           4800  java.util.LinkedHashMap$Entry
  19:           110           4400  java.lang.ref.SoftReference
  20:            91           4368  java.util.WeakHashMap
  21:           256           4096  java.lang.Integer
  22:           121           3872  java.util.Hashtable$Entry
  23:            73           3504  java.util.zip.Inflater
  24:           106           3392  java.util.concurrent.ConcurrentHashMap$Node
  25:            84           3360  sun.nio.cs.UTF_8$Decoder
  26:            98           3136  java.lang.ref.ReferenceQueue
  27:             8           3008  java.lang.Thread
  28:           120           2880  java.io.ExpiringCache$Entry
  29:            88           2816  java.util.zip.ZipCoder
  30:            88           2112  java.util.ArrayDeque
  31:            26           2080  java.lang.reflect.Constructor
  32:            15           1968  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  33:            39           1872  sun.util.locale.LocaleObjectCache$CacheEntry
  34:            38           1824  java.util.HashMap
  35:            73           1752  java.util.zip.ZStreamRef
  36:           100           1600  java.lang.ref.ReferenceQueue$Lock
  37:             1           1568  [[B
  38:            37           1480  java.io.ObjectStreamField
  39:            85           1360  java.lang.Object
  40:            19           1216  java.util.concurrent.ConcurrentHashMap
  41:             9           1184  [Ljava.util.Hashtable$Entry;
  42:            48           1152  java.util.LinkedList$Node
  43:             2           1064  [Ljava.lang.invoke.MethodHandle;
  44:             1           1040  [Ljava.lang.Integer;
  45:             1           1040  [[C
  46:            28            896  java.util.LinkedList
  47:            19            760  sun.util.locale.BaseLocale$Key
  48:             8            640  [S
  49:            19            608  java.io.File
  50:            19            608  java.util.Locale
  51:            19            608  sun.util.locale.BaseLocale
  52:            13            520  java.security.AccessControlContext
  53:            19            456  java.util.Locale$LocaleKey
  54:            18            432  sun.misc.MetaIndex
  55:            17            408  java.util.jar.Attributes$Name
  56:            13            392  [Ljava.io.ObjectStreamField;
  57:             1            384  com.intellij.rt.execution.application.AppMainV2$1
  58:             1            384  java.lang.ref.Finalizer$FinalizerThread
  59:             6            384  java.nio.DirectByteBuffer
  60:             1            376  java.lang.ref.Reference$ReferenceHandler
  61:             6            336  java.nio.DirectLongBufferU
  62:            10            320  java.lang.OutOfMemoryError
  63:             3            312  [D
  64:             2            312  [J
  65:            13            312  sun.reflect.NativeConstructorAccessorImpl
  66:            12            288  java.util.ArrayList
  67:            15            280  [Ljava.lang.Class;
  68:             5            280  sun.util.calendar.ZoneInfo
  69:            11            264  java.net.StandardSocketOptions$StdSocketOption
  70:             8            256  java.util.Vector
  71:             3            240  [Ljava.lang.ThreadLocal$ThreadLocalMap$Entry;
  72:             5            240  java.util.Hashtable
  73:            13            208  sun.reflect.DelegatingConstructorAccessorImpl
  74:             5            200  java.security.ProtectionDomain
  75:             5            200  java.util.WeakHashMap$Entry
  76:             6            192  java.lang.ThreadLocal$ThreadLocalMap$Entry
  77:             4            192  java.util.Properties
  78:             4            192  java.util.TreeMap
  79:             2            160  [[Ljava.lang.String;
  80:             4            160  java.io.FileDescriptor
  81:             4            160  java.lang.ClassLoader$NativeLibrary
  82:             5            160  java.security.CodeSource
  83:             5            160  sun.util.locale.provider.LocaleProviderAdapter$Type
  84:             3            144  java.nio.HeapByteBuffer
  85:             6            144  sun.misc.PerfCounter
  86:             3            144  sun.misc.URLClassPath
  87:             2            128  java.io.ExpiringCache$1
  88:             4            128  java.util.Stack
  89:             1            120  java.net.SocksSocketImpl
  90:             5            120  java.util.Collections$UnmodifiableRandomAccessList
  91:             5            120  sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
  92:             2            112  java.lang.Package
  93:             7            112  java.util.HashSet
  94:             2            112  java.util.LinkedHashMap
  95:             2            112  java.util.ResourceBundle$CacheKey
  96:             4             96  java.lang.RuntimePermission
  97:             2             96  java.lang.ThreadGroup
  98:             6             96  java.lang.ThreadLocal
  99:             1             96  java.net.DualStackPlainSocketImpl
 100:             2             96  java.util.ResourceBundle$BundleReference
 101:             4             96  jdk.net.ExtendedSocketOptions$ExtSocketOption
 102:             4             96  sun.misc.JarIndex
 103:             1             96  sun.misc.Launcher$AppClassLoader
 104:             3             96  sun.net.spi.DefaultProxySelector$NonProxyInfo
 105:             2             96  sun.nio.cs.StreamEncoder
 106:             1             88  sun.misc.Launcher$ExtClassLoader
 107:             5             80  [Ljava.security.Principal;
 108:             2             80  java.io.BufferedWriter
 109:             2             80  java.io.ExpiringCache
 110:             5             80  java.security.ProtectionDomain$Key
 111:             2             80  sun.misc.FloatingDecimal$BinaryToASCIIBuffer
 112:             3             72  java.lang.ThreadLocal$ThreadLocalMap
 113:             3             72  java.net.Proxy$Type
 114:             3             72  java.util.Arrays$ArrayList
 115:             1             72  java.util.ResourceBundle$RBClassLoader
 116:             3             72  java.util.concurrent.atomic.AtomicLong
 117:             3             72  sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
 118:             1             72  sun.util.locale.provider.JRELocaleProviderAdapter
 119:             1             64  [F
 120:             2             64  [Ljava.lang.Thread;
 121:             2             64  java.io.FileOutputStream
 122:             2             64  java.io.FilePermission
 123:             2             64  java.io.PrintStream
 124:             2             64  java.lang.ClassValue$Entry
 125:             2             64  java.lang.VirtualMachineError
 126:             2             64  java.lang.ref.ReferenceQueue$Null
 127:             2             64  java.security.BasicPermissionCollection
 128:             2             64  java.security.Permissions
 129:             2             64  java.util.ResourceBundle$LoaderReference
 130:             2             48  java.io.BufferedOutputStream
 131:             1             48  java.io.BufferedReader
 132:             2             48  java.io.File$PathStatus
 133:             2             48  java.io.FilePermissionCollection
 134:             2             48  java.io.OutputStreamWriter
 135:             2             48  java.net.InetAddress$Cache
 136:             2             48  java.net.InetAddress$Cache$Type
 137:             1             48  java.net.SocketInputStream
 138:             1             48  java.nio.HeapCharBuffer
 139:             2             48  java.nio.charset.CoderResult
 140:             3             48  java.nio.charset.CodingErrorAction
 141:             3             48  java.util.Collections$UnmodifiableSet
 142:             3             48  java.util.HashMap$KeySet
 143:             2             48  sun.misc.NativeSignalHandler
 144:             2             48  sun.misc.Signal
 145:             3             48  sun.net.www.protocol.jar.Handler
 146:             1             48  sun.nio.cs.StreamDecoder
 147:             1             48  sun.nio.cs.US_ASCII$Decoder
 148:             1             48  sun.util.locale.provider.LocaleResources$ResourceReference
 149:             1             40  [Lsun.util.locale.provider.LocaleProviderAdapter$Type;
 150:             1             40  java.io.BufferedInputStream
 151:             1             40  java.util.ResourceBundle$1
 152:             1             40  sun.nio.cs.StandardCharsets$Aliases
 153:             1             40  sun.nio.cs.StandardCharsets$Cache
 154:             1             40  sun.nio.cs.StandardCharsets$Classes
 155:             1             40  sun.nio.cs.ext.ExtendedCharsets
 156:             1             32  [Ljava.lang.OutOfMemoryError;
 157:             2             32  [Ljava.lang.StackTraceElement;
 158:             1             32  [Ljava.lang.ThreadGroup;
 159:             1             32  [Ljava.net.Proxy$Type;
 160:             1             32  java.io.FileInputStream
 161:             1             32  java.io.WinNTFileSystem
 162:             1             32  java.lang.ArithmeticException
 163:             2             32  java.lang.Boolean
 164:             1             32  java.lang.NullPointerException
 165:             1             32  java.net.InetAddress$InetAddressHolder
 166:             1             32  java.net.Socket
 167:             2             32  java.nio.ByteOrder
 168:             2             32  java.util.concurrent.atomic.AtomicInteger
 169:             1             32  java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl
 170:             1             32  jdk.net.ExtendedSocketOptions$1
 171:             1             32  sun.instrument.InstrumentationImpl
 172:             1             32  sun.nio.cs.StandardCharsets
 173:             1             32  sun.util.locale.provider.LocaleResources
 174:             1             32  sun.util.locale.provider.LocaleServiceProviderPool
 175:             1             24  [Ljava.io.File$PathStatus;
 176:             1             24  [Ljava.lang.ClassValue$Entry;
 177:             1             24  [Ljava.net.InetAddress$Cache$Type;
 178:             1             24  [Ljava.security.ProtectionDomain;
 179:             1             24  [Lsun.launcher.LauncherHelper;
 180:             1             24  java.io.InputStreamReader
 181:             1             24  java.lang.ClassValue$Version
 182:             1             24  java.lang.StringBuilder
 183:             1             24  java.lang.invoke.MethodHandleImpl$4
 184:             1             24  java.lang.reflect.ReflectPermission
 185:             1             24  java.net.Inet4Address
 186:             1             24  java.net.Inet6AddressImpl
 187:             1             24  java.net.Proxy
 188:             1             24  java.util.BitSet
 189:             1             24  java.util.Collections$EmptyMap
 190:             1             24  java.util.Collections$SetFromMap
 191:             1             24  java.util.Collections$SynchronizedSet
 192:             1             24  java.util.Locale$Cache
 193:             1             24  java.util.ResourceBundle$Control$CandidateListCache
 194:             1             24  sun.instrument.TransformerManager
 195:             1             24  sun.launcher.LauncherHelper
 196:             1             24  sun.misc.URLClassPath$FileLoader
 197:             1             24  sun.nio.cs.ISO_8859_1
 198:             1             24  sun.nio.cs.ThreadLocalCoders$1
 199:             1             24  sun.nio.cs.ThreadLocalCoders$2
 200:             1             24  sun.nio.cs.US_ASCII
 201:             1             24  sun.nio.cs.UTF_16
 202:             1             24  sun.nio.cs.UTF_16BE
 203:             1             24  sun.nio.cs.UTF_16LE
 204:             1             24  sun.nio.cs.UTF_8
 205:             1             24  sun.util.locale.BaseLocale$Cache
 206:             1             24  sun.util.locale.provider.TimeZoneNameProviderImpl
 207:             1             16  [Ljava.lang.Throwable;
 208:             1             16  [Ljava.security.cert.Certificate;
 209:             1             16  [Lsun.instrument.TransformerManager$TransformerInfo;
 210:             1             16  java.io.FileDescriptor$1
 211:             1             16  java.lang.CharacterDataLatin1
 212:             1             16  java.lang.ClassValue$Identity
 213:             1             16  java.lang.Runtime
 214:             1             16  java.lang.String$CaseInsensitiveComparator
 215:             1             16  java.lang.System$2
 216:             1             16  java.lang.Terminator$1
 217:             1             16  java.lang.invoke.MemberName$Factory
 218:             1             16  java.lang.invoke.MethodHandleImpl$2
 219:             1             16  java.lang.invoke.MethodHandleImpl$3
 220:             1             16  java.lang.ref.Reference$1
 221:             1             16  java.lang.ref.Reference$Lock
 222:             1             16  java.lang.reflect.ReflectAccess
 223:             1             16  java.net.InetAddress$2
 224:             1             16  java.net.URLClassLoader$7
 225:             1             16  java.nio.Bits$1
 226:             1             16  java.nio.charset.CoderResult$1
 227:             1             16  java.nio.charset.CoderResult$2
 228:             1             16  java.security.ProtectionDomain$2
 229:             1             16  java.security.ProtectionDomain$JavaSecurityAccessImpl
 230:             1             16  java.util.Collections$EmptyIterator
 231:             1             16  java.util.Collections$EmptyList
 232:             1             16  java.util.Collections$EmptySet
 233:             1             16  java.util.Hashtable$EntrySet
 234:             1             16  java.util.ResourceBundle$Control
 235:             1             16  java.util.WeakHashMap$KeySet
 236:             1             16  java.util.concurrent.atomic.AtomicBoolean
 237:             1             16  java.util.jar.JavaUtilJarAccessImpl
 238:             1             16  java.util.zip.ZipFile$1
 239:             1             16  jdk.net.ExtendedSocketOptions$PlatformSocketOptions
 240:             1             16  sun.misc.ASCIICaseInsensitiveComparator
 241:             1             16  sun.misc.FloatingDecimal$1
 242:             1             16  sun.misc.Launcher
 243:             1             16  sun.misc.Launcher$Factory
 244:             1             16  sun.misc.Perf
 245:             1             16  sun.misc.Unsafe
 246:             1             16  sun.net.spi.DefaultProxySelector
 247:             1             16  sun.net.www.protocol.file.Handler
 248:             1             16  sun.reflect.ReflectionFactory
 249:             1             16  sun.util.calendar.Gregorian
 250:             1             16  sun.util.locale.provider.AuxLocaleProviderAdapter$NullProvider
 251:             1             16  sun.util.locale.provider.SPILocaleProviderAdapter
 252:             1             16  sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter
 253:             1             16  sun.util.resources.LocaleData
 254:             1             16  sun.util.resources.LocaleData$LocaleDataResourceBundleControl
Total         17443       56945536

五、使用3:其它使用

5.1、jmap -permstat pid

查看系统的ClassLoader信息

5.2、jmap -finalizerinfo

查看堆积在finalizer队列中的对象

六、小结

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

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

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