详解JVM中的本机内存跟踪
JVM内存管理机制中,本机内存是一个重要的概念。本机内存主要指的是JVM所管理的非Java堆内存。在本机内存中,主要包括了本地程序库、直接内存以及堆外内存。
在进行JVM内存跟踪和性能调优时,本机内存也是一个需要我们关注的维度。下文将详细讲解如何进行JVM中的本机内存跟踪。
本机内存的组成部分
JVM中的本机内存主要由以下几部分组成:
1. 本地程序库
本地程序库就是指使用本机语言(如C和C++)编写的动态链接库和静态链接库。对于Java程序而言,本地程序库通常用于提高性能或利用操作系统提供的接口。
如果在Java应用中使用了Java Native Interface(JNI),那么应用程序会与本地程序库进行交互。在JVM中,本地程序库被加载进特殊的本地内存区域中,被称为“native heap”。
2. 直接内存
直接内存是一种可以在JVM中直接使用的内存,它不受Java堆内存大小的限制,且在某些情况下可以提供更高的性能。
直接内存是通过Java NIO包中ByteBuffer的allocateDirect方法实现的。在创建一个ByteBuffer时,可以选择将其分配到Java堆内存中(使用allocate方法),或是分配到本地内存中(使用allocateDirect方法)。
对于前者,JVM会将分配到的堆内存缓存区转换成直接内存缓存区,并且JVM会在针对JVM堆内存进行垃圾回收的同时,也回收删除直接内存缓存区中的无用对象。
3. 堆外内存
堆外内存是指Java堆以外的内存空间,它也是直接内存的一种。与直接内存不同的是,堆外内存通常是在Java代码中通过Java NIO类库进行控制的。
与直接内存一样,堆外内存的申请和释放都不在JVM的控制范围之内,所以也不受JVM中内存管理机制所影响。此外,堆外内存的分配和回收速度相对较快,在大数据处理的场景下具有很好的应用前景。
本机内存跟踪工具
JVM中提供了jstat和jcmd两个命令可以用于监控本机内存使用状况。
1. jstat
jstat命令是JDK自带的一个命令,它可以帮助我们实现对JVM内存的实时监控。
使用jstat命令可以查看本机内存中Native Heap和Direct Memory的使用情况。
-
jstat -gccapacity
:查看本机内存中Native Heap的使用情况,可以得出各代的容量、使用量、占比等信息。 -
jstat -gcutil
:查看本机内存中各代的使用情况,可以得出各代的空间利用率、空间碎片率、对象分配数量等信息。 -
jstat -class
:查看本机内存中的类加载信息,可以得出已加载的类数量、卸载的类数量等信息。
2. jcmd
jcmd命令是在JDK 1.7中引入的命令,它提供了一系列与JVM相关的操作,包括了显示GC概要、启动、停止、线程转储、堆转储、类直方图等。
使用jcmd命令可以查看本机内存中的直接内存使用情况。
- jcmd
VM.native_memory:查看本机内存中的直接内存使用情况,可以得出直接内存的大小、使用量、占比等信息。
示例1:jstat命令查看Native Heap使用情况
下面是一个使用jstat命令查看Native Heap使用情况的示例:
jstat -gccapacity <pid>
输出结果如下:
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC S0 S1 YGC YGCT FGC FGCT GCT
165248.0 165248.0 165248.0 0.0 9688.0 129856.0 131072.0 524288.0 131072.0 131072.0 0.0 9688.0 2864 30.661 3 0.682 31.344
从结果中可以看到,本机内存中的Native Heap总容量为165248KB,Young区容量为 165248KB,Eden区容量为 129856KB,Survivor(S0/S1)区容量为 0KB/9688KB,Old区容量为 131072KB。
示例2:jcmd命令查看直接内存使用情况
下面是一个使用jcmd命令查看直接内存使用情况的示例:
jcmd <pid> VM.native_memory
输出结果如下:
Native Memory Tracking:
Total: 56976720 KB
从结果中可以看到,本机内存中直接内存的大小为56976720KB,可以将其占比计算出。
结论
使用jstat和jcmd命令可以方便地查看JVM本机内存的使用情况,对性能调优非常有帮助。在真实的应用场景中可以根据实际情况使用相关命令。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JVM中的本机内存跟踪 - Python技术站