这些java本机内存从哪里分配?

JDK版本是热点8u_45

我研究了我的java进程的本机内存。 本机内存甚至比堆消耗更多空间。 然而,有许多本机内存块让我感到困惑。 例如pmap -x的结果:

00007f8128000000 65508 25204 25204 rw--- [ anon ] 00007f812bff9000 28 0 0 ----- [ anon ] 00007f812c000000 65508 24768 24768 rw--- [ anon ] 00007f812fff9000 28 0 0 ----- [ anon ] 00007f8130000000 65508 25532 25532 rw--- [ anon ] 00007f8133ff9000 28 0 0 ----- [ anon ] 00007f8134000000 65524 22764 22764 rw--- [ anon ] 00007f8137ffd000 12 0 0 ----- [ anon ] 00007f8138000000 65508 26456 26456 rw--- [ anon ] 00007f813bff9000 28 0 0 ----- [ anon ] 00007f813c000000 65508 23572 23572 rw--- [ anon ] 00007f813fff9000 28 0 0 ----- [ anon ] 00007f8140000000 65520 23208 23208 rw--- [ anon ] 00007f8143ffc000 16 0 0 ----- [ anon ] 00007f8144000000 65512 23164 23164 rw--- [ anon ] 00007f8147ffa000 24 0 0 ----- [ anon ] 00007f8148000000 65516 23416 23416 rw--- [ anon ] 00007f814bffb000 20 0 0 ----- [ anon ] 00007f814c000000 65508 23404 23404 rw--- [ anon ] 00007f814fff9000 28 0 0 ----- [ anon ] 00007f8150000000 65512 24620 24620 rw--- [ anon ] 00007f8153ffa000 24 0 0 ----- [ anon ] 00007f8154000000 65536 23976 23976 rw--- [ anon ] 00007f8158000000 65508 23652 23652 rw--- [ anon ] 00007f815bff9000 28 0 0 ----- [ anon ] 00007f815c000000 65508 23164 23164 rw--- [ anon ] 00007f815fff9000 28 0 0 ----- [ anon ] 00007f8160000000 65508 23344 23344 rw--- [ anon ] 00007f8163ff9000 28 0 0 ----- [ anon ] 00007f8164000000 65508 24052 24052 rw--- [ anon ] 00007f8167ff9000 28 0 0 ----- [ anon ] 00007f8168000000 131052 48608 48608 rw--- [ anon ] 00007f816fffb000 20 0 0 ----- [ anon ] 00007f8170000000 65516 23056 23056 rw--- [ anon ] 00007f8173ffb000 20 0 0 ----- [ anon ] 00007f8174000000 65516 26860 26860 rw--- [ anon ] 00007f8177ffb000 20 0 0 ----- [ anon ] 00007f8178000000 65508 23360 23360 rw--- [ anon ] 00007f817bff9000 28 0 0 ----- [ anon ] 00007f817c000000 65536 24856 24856 rw--- [ anon ] 00007f8180000000 65512 23272 23272 rw--- [ anon ] 00007f8183ffa000 24 0 0 ----- [ anon ] 00007f8184000000 65508 23688 23688 rw--- [ anon ] 00007f8187ff9000 28 0 0 ----- [ anon ] 00007f8188000000 65512 24024 24024 rw--- [ anon ] 00007f818bffa000 24 0 0 ----- [ anon ] 00007f818c000000 65508 25020 25020 rw--- [ anon ] 00007f818fff9000 28 0 0 ----- [ anon ] 00007f8190000000 65512 22868 22868 rw--- [ anon ] 00007f8193ffa000 24 0 0 ----- [ anon ] 00007f8194000000 65508 24156 24156 rw--- [ anon ] 00007f8197ff9000 28 0 0 ----- [ anon ] 00007f8198000000 65508 23684 23684 rw--- [ anon ] 

有许多街区占地约64M。

我使用jcmd pid VM.native_memory细节来跟踪这些内存块。 但是,我找不到具有jcmd结果中列出的任何内存范围的这些块。

此外,我注意到一篇文章提到了在Linux上的glic Java 8和虚拟内存的 malloc中的竞技场效应。 但是这些块似乎与线程池不同,因为1.模式是rw---不是----- 2.竞技场线程池只影响虚拟内存。 它无法解释这些太多的RSS。

我使用gdb来跟踪分配的内存

 dump binary memory mem.bin from to 

mem.bin.1 在此处输入图像描述

mem.bin.2 在此处输入图像描述

mem.bin.3

在此处输入图像描述 mem.bin.4

在此处输入图像描述

大约有30个街区,如图所示。

几天后,我使用Google perf工具来跟踪堆分配。 并发现了这个: 在此处输入图像描述

它表明:zip膨胀消耗近2G内存。 我想这可能与某些编译问题有关。

我已经读过这个问题: https : //bugs.openjdk.java.net/browse/JDK-8164293 。 这与我的担忧有关吗?

那么如何跟踪这些内存块的来源呢?

使用jemalloctcmalloc – 它们都有内置的分配探查器,有助于识别分配的来源。

由于许多原因,Java进程可能使用过多的本机内存。 热门原因是

  • 直接ByteBuffers
  • Unsafe.allocateMemory分配的Unsafe.allocateMemory
  • 未封闭的资源(例如ZipInputStream
  • 其他本地图书馆

请注意,NativeMemoryTracking不会显示本机库消耗的内存。