首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在进行特定系统调用时记录java堆栈跟踪?

在进行特定系统调用时记录java堆栈跟踪?
EN

Stack Overflow用户
提问于 2016-07-08 10:15:37
回答 1查看 301关注 0票数 6

上下文:我正在开发一台基于Java的网络服务器,该服务器意外地泄漏管道。每隔几天,它就会达到40,000个文件描述符和死亡的极限。在死前在服务器上使用lsof显示它被管道堵塞了。管道连接到自己,而不是另一个过程。

代码库中没有一部分创建或使用管道--我们可以看到。

一些较旧版本的JVM在创建套接字时已经创建了一个管道&泄漏了一个管道,但是这在java 1.7.0_75上展示了,我认为它不会受到这个错误的影响。

,我的问题是:使用现代的Linux (例如perf),当进程调用pipe(2)系统调用时,是否有可能对其进行快照--我认为这是创建管道的唯一方式。此外,还可能从其中检索Java堆栈跟踪吗?

考虑到这些信息,应该可以回答“谁在制造管道,为什么?”这个问题。

EN

回答 1

Stack Overflow用户

发布于 2016-07-08 12:38:43

在java 1.7.0_75 (或java 8更新60前)上,您只能从事件调用堆栈上的perf获取有限的信息,因为堆栈将被截断(见下文)。

您可以在sys调用管道时获得系统范围的跟踪点事件,并使用下面的perf命令或类似的命令关闭事件。

代码语言:javascript
复制
perf record -e 'syscalls:sys_enter_pipe*' -e 'syscalls:sys_enter_close' -ag -- sleep 10

要获得完整的堆栈:

  1. 在生产运行前对测试系统进行测试。
  2. 安装Java 8更新60或更高版本
  3. 使用-XX:+PreserveFramePointer运行java以避免截断堆栈
  4. 可选地(因为它不是现成的代码)安装并运行Github的perf-map-agent来解析用于perf的Java符号。
  5. 当问题发生时,运行上面的"perf记录“或类似的
  6. 运行"perf脚本“输出跟踪点事件和相关的堆栈跟踪。

截断的堆栈将是在底部没有线程启动函数的堆栈,例如:

代码语言:javascript
复制
java 19575 [018] 10600910.346655: syscalls:sys_enter_pipe: fildes: 0x7f353b9f7f80
        7f3809cff0b7 __pipe (/usr/lib64/libc-2.17.so)
        7f37f59aecb9 [unknown] (/tmp/perf-19375.map)
        7f37f5e83150 [unknown] (/tmp/perf-19375.map)
    edb4639ef8034082 [unknown] ([unknown])

完整的堆栈看起来可能更像:

代码语言:javascript
复制
java 21553 [009] 10601254.522385: syscalls:sys_enter_pipe: fildes: 0x7f545322f340
        7f54527180b7 __pipe (/usr/lib64/libc-2.17.so)
        7f543d007760 [unknown] (/tmp/perf-21552.map)
        7f543d0007a7 [unknown] (/tmp/perf-21552.map)
        7f5451ce1be6 JavaCalls::call_helper (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
        7f5451fe7b27 Reflection::invoke (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
        7f5451feb237 Reflection::invoke_method (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
        7f5451d705fb JVM_InvokeMethod (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
        7f543da669ed [unknown] (/tmp/perf-21552.map)
        7f543d0007a7 [unknown] (/tmp/perf-21552.map)
        7f5451ce1be6 JavaCalls::call_helper (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
        7f5451d23182 jni_invoke_static (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
        7f5451d3fb8a jni_CallStaticVoidMethod (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
        7f5452bfcbcc JavaMain (/usr/java/jdk1.8.0_60/jre/lib/amd64/jli/libjli.so)
        7f5452e12df5 start_thread (/usr/lib64/libpthread-2.17.so)

与perf代理一起运行,允许perf将JITted未知函数解析为java方法。

还有关于如何做到这一点的各种其他指南,包括Brendan的工作http://techblog.netflix.com/2015/07/java-in-flames.html

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

https://stackoverflow.com/questions/38264181

复制
相关文章

相似问题

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