首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java本机内存“其他”部分消耗了大量内存

Java本机内存“其他”部分消耗了大量内存
EN

Stack Overflow用户
提问于 2022-06-06 23:24:55
回答 1查看 369关注 0票数 1

先决条件

应用程序在带有Java版本"13.0.1“的docker容器中运行,具有以下选项:

-Xmx6G -XX:MaxHeapFreeRatio=30 -XX:MinHeapFreeRatio=10 -XX:+AlwaysActAsServerClassMachine -XX:+UseContainerSupport -XX:+HeapDumpOnOutOfMemoryError -XX:+ExitOnOutOfMemoryError -XX:HeapDumpPath==/.../crush.hprof -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+PrintNMTStatistics -Xlog:gc*:file=/var/log/.../log.gc.log:time::filecount=5,filesize=100000

当我运行jcmd 1 VM.native_memory时,我得到了这样的信息:

代码语言:javascript
复制
Total: reserved=9081562KB, committed=1900002KB
-                 Java Heap (reserved=6291456KB, committed=896000KB)
                            (mmap: reserved=6291456KB, committed=896000KB) 
 
-                     Class (reserved=1221794KB, committed=197034KB)
                            (classes #34434)
                            (  instance classes #32536, array classes #1898)
                            (malloc=7330KB #121979) 
                            (mmap: reserved=1214464KB, committed=189704KB) 
                            (  Metadata:   )
                            (    reserved=165888KB, committed=165752KB)
                            (    used=161911KB)
                            (    free=3841KB)
                            (    waste=0KB =0.00%)
                            (  Class space:)
                            (    reserved=1048576KB, committed=23952KB)
                            (    used=21501KB)
                            (    free=2451KB)
                            (    waste=0KB =0.00%)
 
-                    Thread (reserved=456661KB, committed=50141KB)
                            (thread #442)
                            (stack: reserved=454236KB, committed=47716KB)
                            (malloc=1572KB #2654) 
                            (arena=853KB #882)
 
-                      Code (reserved=255027KB, committed=100419KB)
                            (malloc=7343KB #26005) 
                            (mmap: reserved=247684KB, committed=93076KB) 
 
-                        GC (reserved=316675KB, committed=116459KB)
                            (malloc=47311KB #70516) 
                            (mmap: reserved=269364KB, committed=69148KB) 
 
-                  Compiler (reserved=1429KB, committed=1429KB)
                            (malloc=1634KB #2498) 
                            (arena=18014398509481779KB #5)
 
-                  Internal (reserved=2998KB, committed=2998KB)
                            (malloc=2962KB #5480) 
                            (mmap: reserved=36KB, committed=36KB) 
 
-                     Other (reserved=446581KB, committed=446581KB)
                            (malloc=446581KB #368) 
 
-                    Symbol (reserved=36418KB, committed=36418KB)
                            (malloc=34460KB #906917) 
                            (arena=1958KB #1)
 
-    Native Memory Tracking (reserved=18786KB, committed=18786KB)
                            (malloc=587KB #8291) 
                            (tracking overhead=18199KB)
 
-        Shared class space (reserved=11180KB, committed=11180KB)
                            (mmap: reserved=11180KB, committed=11180KB) 
 
-               Arena Chunk (reserved=19480KB, committed=19480KB)
                            (malloc=19480KB) 
 
-                   Logging (reserved=7KB, committed=7KB)
                            (malloc=7KB #271) 
 
-                 Arguments (reserved=17KB, committed=17KB)
                            (malloc=17KB #471) 
 
-                    Module (reserved=1909KB, committed=1909KB)
                            (malloc=1909KB #11057) 
 
-                 Safepoint (reserved=8KB, committed=8KB)
                            (mmap: reserved=8KB, committed=8KB) 
 
-           Synchronization (reserved=1136KB, committed=1136KB)
                            (malloc=1136KB #6628)

这里我们可以看到“其他”部分消耗446581 KB,而总提交内存是1900002 KB

因此,“其他”部分占用了所有已提交内存的23%!

此外,当应用程序运行时,此内存不会被释放。

因此,我将java标志-XX:NativeMemoryTracking=summary更改为-XX:NativeMemoryTracking=detail,以检查内存分配的位置,并获得以下两个奇怪的内存块:

代码语言:javascript
复制
[0x00007f8db4b32bae] Unsafe_AllocateMemory0+0x8e
[0x00007f8da416e7db]
                             (malloc=298470KB type=Other #286)

[0x00007f8db4b32bae] Unsafe_AllocateMemory0+0x8e
[0x00007f8d9b84bc90]
                             (malloc=148111KB type=Other #82)

分析

  1. 我尝试使用异步分析器来检查事件Unsafe_AllocateMemory0.。

我作为代理运行异步分析器,如下所示:

代码语言:javascript
复制
java -agentpath:/async-profiler/build/libasyncProfiler.so=start,event=itimer,Unsafe_AllocateMemory0,file=/var/log/.../unsafe_allocate_memory.html

得到了这个火焰仪:https://i.stack.imgur.com/PbE5D.png

此外,我还试图对事件malloc,mmap,mprotect进行分析。malloc显示与事件Unsafe_AllocateMemory0相同的照相图,但mmapmprotect的照像仪是空的。

我认为这个问题可能与C2编译器有关,并禁用了它,但是重新启动后没有什么改变-“其他”部分仍然占用了大量的内存。而且,这个应用程序寿命很长,我不确定禁用C2是否是一个好主意。

  1. 我尝试使用jeprof检查代码的哪一部分执行os.malloc

我像这样运行java应用程序:

代码语言:javascript
复制
LD_PRELOAD=/usr/local/lib/libjemalloc.so MALLOC_CONF=prof:true,lg_prof_interval:30,lg_prof_sample:17 exec java -jar /srv/app/myapp.jar

在10+分钟之后,我使用了jeprof,得到了以下内容:https://i.stack.imgur.com/45adD.gif

还有两个内存块占用了许多本地内存。

结果

我找不到分配这么多记忆的地方。

也许有人可以推荐如何找出这个问题的根源?我需要采取哪些措施来避免这个问题呢?

更新1

多亏了阿潘金,我终于找到了这个地方,那里占据了那么多的记忆!

它与Redisson/Lettuce有关,它们在引擎盖下使用Netty:火焰仪

我使用了实验性的本机模式并运行java:

代码语言:javascript
复制
java -agentpath:/async-profiler/build/libasyncProfiler.so=start,event=nativemem,file=/var/log/.../profile.jfr -jar /srv/app/myapp.jar 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-07 00:29:07

你的异步分析器的论点似乎是错的。

event=itimer,Unsafe_AllocateMemory0更改为event=Unsafe_AllocateMemory0

异步分析器还有一个实验性的nativemem模式,专门用于查找本机内存泄漏。详细信息请参见https://github.com/jvm-profiling-tools/async-profiler/discussions/491

NMT中的Other部分通常包括与Unsafe.allocateMemory一起分配的堆外内存,特别是直接ByteBuffers.

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72524403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档