【发布时间】:2016-09-24 10:36:28
【问题描述】:
元空间和原生内存有什么区别?
可以使用 jconsole、jvisualvm、jstat cmds 跟踪元空间。
似乎可以使用 jcmd 跟踪本机内存。 Link
元空间也是本机内存吗?
NIO 缓冲区存储在哪里?在元空间或本机内存中?
【问题讨论】:
标签: java java-8 jvm nio metaspace
元空间和原生内存有什么区别?
可以使用 jconsole、jvisualvm、jstat cmds 跟踪元空间。
似乎可以使用 jcmd 跟踪本机内存。 Link
元空间也是本机内存吗?
NIO 缓冲区存储在哪里?在元空间或本机内存中?
【问题讨论】:
标签: java java-8 jvm nio metaspace
元空间也是本机内存吗?
是的,元空间是本机内存(进程内存)的一部分,并且是 受主机操作系统限制
您可以使用jmap -permstat PID 对其进行监控。如果您的应用程序最终在元空间中分配了大量内存,那么它将影响 整个系统 而不仅仅是 JVM。这就是为什么它建议您使用 -XX:MetaspaceSize 为您的应用程序显式设置最大元空间大小.
Java NIO API 使用 ByteBuffers 作为 I/O 的源和目标 调用,并有两种风格:
- 堆字节缓冲区(包装一个 byte[] 数组,分配在垃圾回收的 Java 堆中)
- 直接字节缓冲区(包装在 Java 堆外分配的内存)
由于只有“本机”内存可以传递给操作系统调用,所以 它不会被垃圾收集器移动,这意味着当你使用 用于 I/O 的 heap ByteBuffer,它被复制到 临时直接 字节缓冲区。 JDK 为每个线程缓存一个临时缓冲区,没有 任何内存限制(即无限缓存)。因此,如果您 从多个线程调用具有大堆 ByteBuffers 的 I/O 方法, 您的进程可能会使用大量额外的本机内存。
您可以参考this和this article了解更多详情。
更新
RSS=OffHeap(映射文件、JVM 内部代码(.bss 段)、线程堆栈、直接缓冲区)+ GC 内部结构+ 堆 + 本地库(例如 IO 库)使用和分配的结构+ 元空间 + JVM 的共享库 + CodeCache
您可以在 linux 上使用 pmap -x 来分析您的 JVM 进程的内存映射。此外,Jemalloc 可以通过设置适当的MALLOC_CONF env variables,帮助在每 x GB/x kB 的内存分配/堆栈跟踪之后将配置文件写入磁盘。生成文件后,请尝试使用
Jeprof for visualisation。例如。
jeprof --show_bytes --pdf `which w` jeprof.heap > sample.pdf
为调用图生成 PDF。
【讨论】:
ps unix cmd 中的 RSS 值与(堆+元空间)不匹配。因此,如果本机内存超过元空间,如何衡量它。如果可能的话,您能否提及所用内存的分解(RSS)
pmap - x更深入地了解内存。