Mar*_*wie 6 java linux pipe stack-trace perf
上下文:我正在研究一个基于Java的网络服务器,它意外地泄漏了管道.它每隔几天就达到40,000个文件描述符的限制并死掉.lsof在死亡之前在服务器上使用显示它被管道堵塞.管道连接到自身,而不是另一个过程.
代码库的任何部分都不会创建或使用管道 - 我们可以看到.
一些旧版本的JVM在创建套接字时创建并泄漏了一个管道,但是这在java 1.7.0_75上展示,我相信它不会遭受这个bug.
我的问题是:使用现代Linux工具链(例如perf)可以在调用pipe(2)系统调用时对进程进行快照- 我认为这是创建管道的唯一方法.此外,是否有可能从中检索Java堆栈跟踪?
鉴于此信息,应该可以回答"谁在创建管道,为什么?"这一问题.
小智 3
在 java 1.7.0_75(或 java 8 update 60 之前的版本)上,您只能从事件的调用堆栈上的 perf 获取有限的信息,因为堆栈将被截断(见下文)。
您可以使用以下 perf 命令或类似命令获取对管道和关闭的 sys 调用的系统范围跟踪点事件。
perf record -e 'syscalls:sys_enter_pipe*' -e 'syscalls:sys_enter_close' -ag -- sleep 10
Run Code Online (Sandbox Code Playgroud)
要获得完整的堆栈:
截断的堆栈将是底部没有线程启动函数的堆栈,例如:
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])
Run Code Online (Sandbox Code Playgroud)
完整的堆栈可能看起来更像:
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)
Run Code Online (Sandbox Code Playgroud)
使用 perf-map-agent 运行以允许 perf 将 JITted [未知] 函数解析为 java 方法。
还有各种其他关于如何执行此操作的指南,包括 Brendan Gregg 的工作http://techblog.netflix.com/2015/07/java-in-flames.html
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |