jemalloc and JVM_FindSignal



正如在这个问题中已经回答的:JVM_FindSignal函数连续分配本地内存

jemalloc报告JVM_FindSignal的泄漏与缺少调试符号有关。我当然安装了调试符号,请参阅:

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) 

还有什么需要考虑的吗?

事实证明

  1. openjdk-8-dbg软件包将带有调试符号的文件安装到/usr/lib/debug/.build-id
  2. jeprof/usr/lib/debug/{FULL_SO_PATH}中查找调试符号

因此,这是jeprof中不解析.note.gnu.build-id部分的错误和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+本机堆栈。使用异步探查器分析mallocmprotectmmap调用有助于发现Java应用程序中的本机内存泄漏。有关详细信息,请参阅此答案。

这里有一个jeprof的补丁,它可以更智能地查找调试符号。这是基于@apaingin的回答。

https://github.com/jemalloc/jemalloc/pull/2059/files

相关内容

  • 没有找到相关文章

最新更新