目录

一、jmap:导出内存映像文件&内存使用情况

二、导出dump堆转储快照文件

三、显示堆内存相关信息

四、其它作用

五、小结


一、jmap:导出内存映像文件&内存使用情况

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

C:\Users\WSH>jmap -h
Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a core file)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -clstats             to print class loader statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system

官方帮助文档:jmap

基本使用语法为:

  • jmap [option] <pid>
  • jmap [option] <executable <core>
  • jmap [option] [server_id@] <remote server IP or hostname>

option参数说明如下:

选项

作用

-dump

生成dump文件(Java堆转储快照),-dump:live只保存堆中的存活对象

-heap

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

-histo

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

-J <flag>

传递参数给jmap启动的jvm

-finalizerinfo

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

-permstat

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

-F

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

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

二、导出dump堆转储快照文件

dump堆转储快照文件主要有手动和自动两种方式:

【a】手动方式

手动dump出堆转储快照文件:如下两个选择其一即可

//dump出所有对象
> jmap -dump:format=b,file=<filename.hprof> <pid>
//只dump出存活对象(live)
> jmap -dump:live,format=b,file=<filename.hprof> <pid>

示例:

public class GCTest {
    public static void main(String[] args) throws ClassNotFoundException {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            byte[] arr = new byte[1024 * 100];
            list.add(arr);
            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

设置JVM参数并启动程序:

-Xms60m -Xmx60m -XX:SurvivorRatio=8

手动dump出堆转储快照文件:

C:\Users\WSH>jmap -dump:format=b,file=d:\1.hprof 14904
Dumping heap to D:\1.hprof ...
Heap dump file created

C:\Users\WSH>jmap -dump:format=b,file=d:\2.hprof 14904
Dumping heap to D:\2.hprof ...
Heap dump file created

C:\Users\WSH>jmap -dump:format=b,file=d:\3.hprof 14904
Dumping heap to D:\3.hprof ...
Heap dump file created

##########只dump存活的对象###########
C:\Users\WSH>jmap -dump:live,format=b,file=d:\4.hprof 14904
Dumping heap to D:\4.hprof ...
Heap dump file created

如下图,即为生成的堆转储快照文件,可借助一些可视化分析工具打开,后面我们会介绍。

java自带的jmap命令可以dump jmap dump内存的命令_java自带的jmap命令可以dump

【b】自动方式

  • -XX:+HeapDumpOnOutOfMemoryError:在堆溢出的时候可以储存快照;
  • -XX:HeapDumpPath=d:/dumps/:导出内存快照时保存的路径;

在启动程序的时候指定上述两个参数即可,如下图: 

java自带的jmap命令可以dump jmap dump内存的命令_java_02

三、显示堆内存相关信息

【a】jmap -heap 928:查看堆各区域的使用情况

C:\Users\WSH>jmap -heap 928
Attaching to process ID 928, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.291-b10

using thread-local object allocation.
Parallel GC with 10 thread(s)

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)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 15728640 (15.0MB)
   used     = 1623088 (1.5478973388671875MB)
   free     = 14105552 (13.452102661132812MB)
   10.319315592447916% used
From Space:
   capacity = 2621440 (2.5MB)
   used     = 2589008 (2.4690704345703125MB)
   free     = 32432 (0.0309295654296875MB)
   98.7628173828125% used
To Space:
   capacity = 2621440 (2.5MB)
   used     = 0 (0.0MB)
   free     = 2621440 (2.5MB)
   0.0% used
PS Old Generation
   capacity = 41943040 (40.0MB)
   used     = 10146216 (9.676185607910156MB)
   free     = 31796824 (30.323814392089844MB)
   24.19046401977539% used

3182 interned Strings occupying 260960 bytes.

【b】jmap -histo 928:查看实例柱数状图

C:\Users\WSH>jmap -histo 928

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

四、其它作用

jmap -permstat 15144:查看系统的ClassLoader信息;

jmap -finalizerinfo 15144:查看堆积在finalizer队列中的对象;

注意,上述两个参数仅在linux/solaris平台有效。

五、小结

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

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

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