当前位置: 首页 > 知识库问答 >
问题:

为什么JVM的本机内存跟踪报告会报告线程中竞技场区域的内存使用率如此之高

吕嘉荣
2023-03-14

我有一个问题,我有一个java应用程序,偶尔会在运行内存溢出后被linux中的oom杀手杀死。我已经监控了堆,它不会增长。事实上,它甚至从来没有通过Xmx达到允许的最大值,这是768MB

因此,我通过-XX: NativeMemoryTrack=摘要启用了本机内存跟踪。然后我运行我的应用程序,取一个基线,然后等到它开始吞噬内存的时候,这时我使用了jcmd

Native Memory Tracking:

Total: reserved=16894180KB +14703341KB, committed=15330936KB +14896985KB

-                 Java Heap (reserved=786432KB, committed=450048KB +129536KB)
                            (mmap: reserved=786432KB, committed=450048KB +129536KB)

-                     Class (reserved=1185329KB +110708KB, committed=156657KB +128180KB)
                            (classes #23288 +19829)
                            (malloc=11825KB +2164KB #27117 +23990)
                            (mmap: reserved=1173504KB +108544KB, committed=144832KB +126016KB)

-                    Thread (reserved=16825159KB +16803246KB, committed=16825159KB +16803246KB)
                            (thread #47 +24)
                            (stack: reserved=47288KB +25472KB, committed=47288KB +25472KB)
                            (malloc=153KB +82KB #240 +120)
                            (arena=16777717KB +16777692 #92 +48)

-                      Code (reserved=260509KB +9756KB, committed=63625KB +56100KB)
                            (malloc=10909KB +9756KB #14012 +11850)
                            (mmap: reserved=249600KB, committed=52716KB +46344KB)

-                        GC (reserved=39135KB +15KB, committed=37831KB +307KB)
                            (malloc=10399KB +15KB #629 +478)
                            (mmap: reserved=28736KB, committed=27432KB +292KB)

-                  Compiler (reserved=890284KB +890139KB, committed=890284KB +890139KB)
                            (malloc=55KB +41KB #334 +258)
                            (arena=890229KB +890098 #8 +5)

-                  Internal (reserved=13299KB +3377KB, committed=13299KB +3377KB)
                            (malloc=13267KB +3377KB #26649 +21418)
                            (mmap: reserved=32KB, committed=32KB)

-                    Symbol (reserved=32729KB +27117KB, committed=32729KB +27117KB)
                            (malloc=28565KB +24400KB #285695 +250801)
                            (arena=4163KB +2717 #1)

-    Native Memory Tracking (reserved=13011KB +12136KB, committed=13011KB +12136KB)
                            (malloc=367KB +241KB #5803 +3803)
                            (tracking overhead=12644KB +11895KB)

-               Arena Chunk (reserved=18014398506330278KB -3153154KB, committed=18014398506330278KB -3153154KB)
                            (malloc=18014398506330278KB -3153154KB)

从报告中,我可以看到使用的内存量显著增加了committed=15330936KB 14896985KB,但这不在堆中。

这似乎发生在线程使用的内存中。堆栈本身看起来很正常,因为每个线程堆栈应该是1024KB,所以47288KB对于47个线程来说是合理的。

Thread (reserved=16825159KB +16803246KB, committed=16825159KB +16803246KB)
                            (thread #47 +24)
                            (stack: reserved=47288KB +25472KB, committed=47288KB +25472KB)
                            (malloc=153KB +82KB #240 +120)
                            (arena=16777717KB +16777692 #92 +48) 

特别是,它报告称竞技场增加了16777692。这是什么原因造成的?为什么?或者这不是一个问题?从我在网上看到的其他报告(包括其他stackoverflow问题)来看,arena的内存使用率从未像现在这样高。

此外,就保留的规模而言,竞技场本身也是巨大的。这正常吗?如果不正常,是什么导致这种异常

以下打开的JDK bug JDK-8164293似乎报告了JVM本身的内存泄漏,所以我可能遇到了这个bug吗?


共有2个答案

东郭远航
2023-03-14

只是一个观察——荒谬的“竞技场块”在2^63/2^64处工作。这可能是一个溢出错误,但同样也可能只是一些深层机制,它被告知有整个地址空间可以使用。

岳锦
2023-03-14

我们有类似的问题,这是开放的,仍在调查中。你可以看到下面的链接私人字节增加javaw进程在java8

但我还是想在这里分享我的分析。

1) 竞技场的增加没有映射到堆。所以这显然不是java代码的问题。从这个角度看,它看起来像是JNI代码问题或java api内部的本机泄漏。因此,跟踪JNI代码,看看是否正在关闭所有malloc调用,并对所有本机java对象使用deleteLocalRef和deleteGlobalRef。

2)检查是否只有在java更新后才会出现这个问题。如果是,那么检查您在代码中使用的jni. h和相关文件。是来自java8吗?

3)如果仍然没有运气,那么使用像Jemalloc这样的工具,它可以告诉你导致最大泄漏的方法名称。看来这是linux最好的工具。

看看这个链接:https://gdstechnology.blog.gov.uk/2015/12/11/using-jemalloc-to-get-to-the-bottom-of-a-memory-leak/

4) 您可以使用VADump之类的工具查看哪个dll消耗的内存最多。

我们的调查仍在进行中,如果有任何结果,我会及时通知你。请在此更新您的进度。

 类似资料:
  • 本文向大家介绍详解JVM中的本机内存跟踪,包括了详解JVM中的本机内存跟踪的使用技巧和注意事项,需要的朋友参考一下 1.概述 有没有想过为什么Java应用程序通过众所周知的-Xms和-Xmx调优标志消耗的内存比指定数量多得多?出于各种原因和可能的优化,JVM可以分配额外的本机内存。这些额外的分配最终会使消耗的内存超出-Xmx限制。 在本教程中,我们将列举JVM中的一些常见内存分配源,以及它们的大小

  • 我有一个JVM,它报告提交的堆内存约为8GB(其他部分应该在此之上)。但我的操作系统显示内存使用量约为5GB。我理解由于非堆、metaspace等原因,内存使用量可能会超过提交的内存,但是怎么可能使用量比JVM报告的要少呢? 本机内存跟踪器(NMT)的输出显示保留内存为~11 GB OS-Debian 9 爪哇-

  • 当运行启用了本机内存跟踪的Java应用程序(在YARN中)(请参见https://docs.oracle.com/javase/8/docs/technotes/guides/vm/nmt-8.html和https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html)时,我可以看到JVM在不

  • 问题内容: 在启用了本机内存跟踪的Java应用程序(在YARN中)运行时(请参阅https://docs.oracle.com/javase/8/docs/technotes/guides/vm/nmt-8.html和https:// docs。 oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html ),我

  • Java1.8。0_131 Windows Server 2012 R2。 “-Xmx=9000m”。但是Windows任务管理器显示java进程使用的内存超过14GB。 NMT显示“内部”消耗超过4.5 GB的内存。为什么会出现这种情况?我知道为本机内存定义空间不是Java功能。但是有什么方法可以限制“内部”内存吗? 总计:保留=15782485KB,提交=14653869KB-Java堆(保留

  • 我用两个不同的GTM容器为两个不同的域设置了跨域跟踪。我添加了两个域,a.com和b.com在两个通用分析标签的自动链接域中,将允许链接器设置为真,并将Cookie域设置为自动。然而,当我从脸谱网浏览网站a.com并点击b.com时,我在谷歌分析的实时报告中看到a.com/推荐作为流量来源。这应该是Facebook吧?有人有调试此问题的方法吗? 谢谢