正如在这个问题中已经回答的:FindSignal函数连续分配本机内存
来自JVM_FindSignal的jemalloc报告泄漏与缺少调试符号有关。我当然安装了调试符号,请参见:
rbs42@rbs42-VirtualBox:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/server$ gdb libjvm.so -ex 'info address UseG1GC'
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from libjvm.so...
Reading symbols from /usr/lib/debug/.build-id/16/240e0172c3fc0dd6e974325c8ad1d93723ccac.debug...
(No debugging symbols found in /usr/lib/debug/.build-id/16/240e0172c3fc0dd6e974325c8ad1d93723ccac.debug)
Installing openjdk unwinder
Traceback (most recent call last):
File "/usr/share/gdb/auto-load/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so-gdb.py", line 52, in <module>
class Types(object):
File "/usr/share/gdb/auto-load/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so-gdb.py", line 66, in Types
nmethodp_t = gdb.lookup_type('nmethod').pointer()
gdb.error: No type named nmethod.
Symbol "UseG1GC" is at 0xd189b2 in a file compiled without debugging.不过,我的jeprof输出如下:
rbs42@rbs42-VirtualBox:/media/rbs42/data/Gebos/RBS42/run/sms50$ jeprof --show_bytes /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java jeprof.22104.0.f.heap
Using local file /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java.
Using local file jeprof.22104.0.f.heap.
Welcome to jeprof! For help, type 'help'.
(jeprof) top
Total: 33502504 B
20958503 62.6% 62.6% 21342909 63.7% JVM_FindSignal
8388608 25.0% 87.6% 8388608 25.0% SNX11B1A
1481379 4.4% 92.0% 1481379 4.4% inflate
1151253 3.4% 95.5% 1151253 3.4% Java_java_util_zip_ZipFile_getZipMessage
426303 1.3% 96.7% 426303 1.3% SNE00B1A
404065 1.2% 97.9% 404065 1.2% inflateInit2_
253077 0.8% 98.7% 20393297 60.9% SUNWprivate_1.1
176271 0.5% 99.2% 176271 0.5% std::__throw_ios_failure
131713 0.4% 99.6% 131713 0.4% _dl_new_object
131328 0.4% 100.0% 131328 0.4% _dl_check_map_versions
(jeprof) 还有什么要考虑的吗?
发布于 2020-09-24 00:44:59
结果证明
openjdk-8-dbg包将带有调试符号的文件安装到/usr/lib/debug/.build-id中。jeprof在/usr/lib/debug/{FULL_SO_PATH}中查找调试符号因此,它是jeprof中一个不解析.note.gnu.build-id部分的bug和一个不包含调试库的完整路径符号链接的dbg包的问题的组合。
要解决这个问题,您可以手动创建相应的符号链接:
ln -s /usr/lib/debug/.build-id/16/240e0172c3fc0dd6e974325c8ad1d93723ccac.debug /usr/lib/debug/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so(文件名取自gdb输出)
然而,即使当jeprof能够读取调试符号时,这对于Java应用程序也没有什么帮助。问题是jemalloc不知道如何展开Java堆栈。有关示例,请参见这份报告。
考虑尝试可以显示混合异步分析器堆栈的Java+native。使用异步分析器分析malloc、mprotect和mmap调用有助于查找Java应用程序中的本机内存泄漏。详情请参见这个答案。
发布于 2021-04-19 04:05:47
以下是jeprof的修补程序,它使查找调试符号变得更聪明。这是基于@apangin的回答。
https://stackoverflow.com/questions/64036028
复制相似问题