Native Memory里存些什么?DirectBuffer的好处
- 管理java heap的状态数据(用于GC);
- JNI调用,也就是Native Stack;
- JIT(即使编译器)编译时使用Native Memory,并且JIT的输入(Java字节码)和输出(可执行代码)也都是保存在Native Memory;
- NIO direct buffer。对于IBM JVM和Hotspot,都可以通过-XX:MaxDirectMemorySize来设置nio直接缓冲区的最大值。默认是64M。超过这个时,会按照32M自动增大。
- 对于IBM的JVM某些版本实现,类加载器和类信息都是保存在Native Memory中的。
- DirectBuffer访问更快,避免了从HeapBuffer还需要从java堆拷贝到本地堆,操作系统直接访问的是DirectBuffer。DirectBuffer对象的数据实际是保存在native heap中,但是引用保存在HeapBuffer中。
- 另外,DirectBuffer的引用是直接分配在堆得Old区的,因此其回收时机是在FullGC时。因此,需要避免频繁的分配DirectBuffer,这样很容易导致Native Memory溢出。
jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]
# summary: 分类内存使用情况.
# detail: 详细内存使用情况,除了summary信息之外还包含了虚拟内存使用情况。
# baseline: 创建内存使用快照,方便和后面做对比
# summary.diff: 和上一次baseline的summary对比
# detail.diff: 和上一次baseline的detail对比
# shutdown: 关闭NMT
1.导出内存模型文件
jmap -dump:format=b,file=dumpfile.hprof
2.运行配置native查看
java -XX:NativeMemoryTracking=summary -jar server-examples-0.4.3-
SNAPSHOT.jar
3.native查看
jcmd pid VM.native_memory summary
4.native内存基线设置
jcmd pid VM.native_memory baseline
5.diff查看
jcmd pid VM.native_memory summary.diff
6. shutdown时输出
-XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics
使用上述命令可以在jvm shutdown的时候输出整体的native memory统计
7.关闭
jcmd pid VM.native_memory shutdown
summmary
262144是256M 因为该Java启动参数最大堆设为了256M:-Xmx256M
8.
我们知道,Java进程的内存包括Java NonHeap空间、Java Heap空间和Native Heap空间和,既然内存不是被Java NonHeap/Heap空间吃掉的,那么只能怀疑是被Native Heap空间吃掉的
那么maxMemory()是用native来实现的,我们来看看java文档是如何说说它的返回。
*The maxMemory() method returns the maximum amount of memory that the VM
will attempt to use, allowing applications to better manage memory load.
If the implementation-dependent -Xmx flag is used then this method will
return that value.*
可见默认设置和Heap的Size差不多。在我们系统中使用了第三方lib,要求使用最少1G的Direct Memory Size。而我们系统中Xmx设置是512M。所以我们加入了MaxDirectMemorySize参数来指定DirectMemoryArea大小。
在程序中中可以获得-XX:MaxDirectMemorySize的设置的值。
这篇文章不错: