使用gcore生成的Java核心文件有用吗?

问题描述 投票:2回答:2

我们有一个JAVA应用程序,它通过消耗一些(未知的)资源来阻止其他组件创建新线程,从而使我们的redhat服务器(30核/ 512Go ram)崩溃了,我们目前正在解决这是通过杀死每次导致问题的垃圾线程(大约每15天一次)来杀死的,我们试图在/ etc / security / limits.conf上设置巨大的值,但是在达到此目的之前我们已经找到了问题的出路。限制。

我上一次使用ps -efL | wc -l,对于我们的野兽来说,10000线程很多吗?知道那时的CPU / RAM消耗很低吗?我使用gstack尝试找出它卡在哪里,但是由于它是一个JAVA程序idk,如果输出有意义?但我可以在那里找到一个模式:9000个线程中的大多数看起来都像这样:

Thread 9049 (Thread 0x7f43d5087700 (LWP 123925)):
#0  0x00007f43d791e705 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00007f43d6a94f33 in os::PlatformEvent::park() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#2  0x00007f43d6a58e67 in Monitor::IWait(Thread*, long) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#3  0x00007f43d6a59786 in Monitor::wait(bool, long, bool) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#4  0x00007f43d6c48e1b in GangWorker::loop() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#5  0x00007f43d6a9bd48 in java_start(Thread*) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#6  0x00007f43d791adf5 in start_thread () from /lib64/libpthread.so.0
#7  0x00007f43d722f1ad in clone () from /lib64/libc.so.6
Thread 9048 (Thread 0x7f43d4f86700 (LWP 123926)):
#0  0x00007f43d791e705 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00007f43d6a94f33 in os::PlatformEvent::park() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#2  0x00007f43d6a58e67 in Monitor::IWait(Thread*, long) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#3  0x00007f43d6a59786 in Monitor::wait(bool, long, bool) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#4  0x00007f43d6c48e1b in GangWorker::loop() () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#5  0x00007f43d6a9bd48 in java_start(Thread*) () from /opt/3pp/jdk1.8.0_25/jre/lib/amd64/server/libjvm.so
#6  0x00007f43d791adf5 in start_thread () from /lib64/libpthread.so.0
#7  0x00007f43d722f1ad in clone () from /lib64/libc.so.6

也在杀死我使用过的进程[[gcore -o /tmp/dump.txt之前,这是获取Java进程核心文件的正确方法吗?

当我尝试使用

gdb

进行查看时,得到没有调试符号不是核心转储,这是检查此类文件的正确方法吗?M1:~# gdb /opt/3pp/jre/bin/java /tmp/dump.txt.123913 GNU gdb (GDB) Copyright (C) 2013 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-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /opt/3pp/jre/bin/java...(no debugging symbols "/tmp/dump.txt.123913" is not a core dump: File format not recognized Missing separate debuginfos, use: debuginfo-install jre1.8.0_25-1.8.0_25-fcs.x86_64
提前感谢您的时间。
java linux jvm gdb gcore
2个回答
1
投票
我上次使用ps -efL计数了线程数| wc -l,知道当时的CPU / RAM消耗很低,对于我们的野兽来说,有10000个线程很多吗?
这不是数量可观的线程,但不是,10K线程不是很多,特别是对于30核计算机而言。我目前使用的4核心Windows桌面大约有3K。

我使用gstack尝试找出它被卡在哪里,但是由于它是一个JAVA程序idk,如果输出有意义?

我从未尝试使用本机线程堆栈调试Java,但是在我看来,该堆栈跟踪看起来像一个“驻留”线程。换句话说,某个线程池中的某个线程与工作无关,因此正在等待工作。有关更多详细信息,请参见this答案。

也在杀死进程之前,我使用了gcore -o /tmp/dump.txt,这是获取Java进程核心文件的正确方法吗?

它可能具有一定的价值,但我建议为该工作使用特定于Java的工具。首先想到的是JDK附带的jcmdHere's a link让您开始。 Java 9的版本具有一些nicer documentation,并且非常相似。

[我专门要做的是使用Thread.printjcmd命令打印Java级别的堆栈跟踪,并使用GC.heap_dump将整个Java堆转储到.hprof文件中,然后可以通过工具对其进行分析。例如MAT

[如果您将JDK 8与"Commercial Features"一起使用,则还可以启用JFR (Java Flight Recorder来跟踪过程的执行。可以使用Oracle's "Mission Control"或其他“任务控制”(例如the one from Azul, called Zulu)打开JFR创建的文件。

最后,您也可以尝试使用jconsole连接到该进程,这是JDK附带的另一个工具。

祝你好运。>>

我将为您提供有关JVM核心文件的一般建议,以便您可以选择是否深入研究。

使用gcore生成的Java核心文件有用吗?

它确实很有用,但是如果您不知道特定的JVM实现,它看起来就像一团糟。 stacktraces完全正确,并且由于调用pthread_cond_wait而绝对不会发生崩溃(除非pthread本身是错误的,这是极不可能的)。

我们有一个崩溃的JAVA应用程序

您是否进行了内存测试?在大多数情况下,JVM HotSpot实施都是高度可靠的。

获取Java进程的核心文件的正确方法吗?

您也可以在gdb中使用generate-core-file

没有调试符号

您已经显示了带有调试符号的堆栈跟踪。核心文件可能有问题。试试gdb generate-core-file

如果您想深入研究HotSpot核心转储,那么我可以建议您按照以下顺序进行操作:

info threads查找“崩溃线程”

使用thread N转到该线程,其中N是“崩溃线程”数字

    disas取消该功能并找出导致崩溃的指令
  1. 如果是由于取消引用垃圾指针而发生的情况,则将其向下反转以找出值的来源
  2. 如果由于不正确的Bus Error使用而使诸如mmap之类的文件崩溃,情况会变得复杂。万一您陷入JIT编译方法的崩溃,事情将变得更加复杂,因此btdisas和朋友将不再有用。可行的方法是通过nmethodcode_offset转储编译的代码,并尝试找出问题所在。

0
投票
使用gcore生成的Java核心文件有用吗?
© www.soinside.com 2019 - 2024. All rights reserved.