上下文 :我正在处理一个基于Java的networking服务器,意外泄漏pipe道。 每隔几天它就会达到40,000个文件描述符的限制并死亡。 在死亡之前在服务器上使用lsof显示它被pipe道阻塞。 pipe道连接到自己,而不是另一个进程。
代码库的任何部分都不会创build或使用pipe道 – 我们可以看到。
一些旧版本的JVM在创build套接字时已经创build并泄露了一个pipe道,但是这在java 1.7.0_75上展现出来,我相信它不会遭受这个错误。
我的问题是 :使用现代linux工具链(如perf)可以在调用pipe(2)系统调用时快照进程 – 我相信这是pipe道创build的唯一方式。 此外,是否有可能从那里检索Java堆栈跟踪?
鉴于这些信息,应该可以回答“谁在创buildpipe道,为什么?”这个问题。
在java 1.7.0_75(或java之前的版本8更新60)上,只能从事件的调用堆栈中获得有限的信息,因为堆栈将被截断(见下文)。
您可以将系统调用中的全系统跟踪点事件传递给管道,并使用以下perf命令或类似命令关闭。
perf record -e \’syscalls:sys_enter_pipe*\’ -e \’syscalls:sys_enter_close\’ -ag — sleep 10
要获得完整的堆栈:
在生产之前在测试系统上进行测试。
安装Java 8更新60或更高版本
使用-XX:+ PreserveFramePointer运行java以避免截断堆栈
可选地(因为它不是生产就绪代码)安装并运行Github中的perf-map-agent来解析用于perf的Java JIT符号
发生问题时,运行上述“性能记录”或类似内容
运行“perf脚本”输出跟踪点事件和关联的堆栈跟踪
截断的堆栈将是底部没有线程启动功能的堆栈,例如:
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])
完整的堆栈可能看起来更像:
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-map-agent运行以允许perf将JITted [未知]函数解析为java方法。
关于如何做到这一点的其他指南还包括Brendan Gregg的工作http://techblog.netflix.com/2015/07/java-in-flames.HTML
总结
以上是内存溢出为你收集整理的在进行特定的系统调用时loggingjava堆栈跟踪?全部内容,希望文章能够帮你解决在进行特定的系统调用时loggingjava堆栈跟踪?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
请登录后查看评论内容