为什么这个Java进程无法终止?【JAVA教程】

!
也想出现在这里? 联系我们
信息

为什么这个Java进程无法终止?,第1张

概述为什么这个Java进程无法终止

我在构build服务器上有一个间歇性的问题,构build中的Java进程无法终止,似乎永远继续运行(使用100%的cpu)永远(我已经看到它在周末运行2天以上通常需要大约10分钟)。 kill -9 pID似乎是停止进程的唯一方法。

我已经尝试过在进程中调用kill -QUIT pID ,但似乎没有产生任何堆栈跟踪到STDOUT(也许它没有响应信号?)。 没有-F强制选项的Jstack似乎无法连接到正在运行的JVM,但是使用强制选项,它会产生下面的输出。

不幸的是,即使有这个堆栈跟踪,我也看不到有任何明显的path可供进一步调查。

据我可以告诉它显示了两个已经运行Object.wait的“BLOCKED”线程(它们的堆栈似乎只包含核心Java代码,没有我们的代码),第三个是没有堆栈输出的“IN_VM”。

使用linux错误注入框架

为什么我们需要在windows平台上有pdb文件的时候使用map文件呢?

解释gfortran错误追溯

在托pipe服务中检测到CRTdeBUGging堆损坏

任何方式来停止x86_64上的c + +标准库的未alignment的访问?

我应该采取哪些步骤来收集有关问题原因的更多信息(或者更好,但我该如何解决)?

$ /opt/jdk1.6.0_29/bin/Jstack -l -F 5546

附加到进程ID 5546,请稍候…

deBUGging器成功连接。

检测到服务器编译

JVM版本是20.4-b02

死锁检测:

没有发现死锁。

使用Printezis位查找对象大小并跳过…

线程5555 :(状态= BLOCKED)

locking拥有同步器:

– 没有

线程5554 :(状态= BLOCKED)

– java.lang.Object.wait(long)@ bci = 0(解释帧)

– java.lang.ref.ReferenceQueue.remove(long)@ bci = 44,line = 118(Interpreted frame)

– java.lang.ref.ReferenceQueue.remove()@ bci = 2,line = 134(Interpreted frame)

– java.lang.ref.Finalizer $ FinalizerThread.run()@ bci = 3,line = 159(Interpreted frame)

locking拥有同步器:

– 没有

线程5553 :(状态= BLOCKED)

– java.lang.Object.wait(long)@ bci = 0(解释帧)

– java.lang.Object.wait()@ bci = 2,line = 485(Interpreted frame)

– java.lang.ref.Reference $ ReferenceHandler.run()@ bci = 46,line = 116(Interpreted frame)

locking拥有同步器:

– 没有

线程5548 :(状态= IN_VM)

locking拥有同步器:

– 没有

(Java版本1.6.0更新29,在ScIEntific linux版本6.0上运行)

更新:

运行strace -f -p 894产生了一个似乎层出不穷的…

[pID 900] sched_yIEld() = 0 [pID 900] sched_yIEld() = 0 …

然后当Ctrl-Cd

Process 894 detached … Process 900 detached … Process 909 detached

jmap -histo 894不连接,但jmap -F -histo 894返回…

附加到进程ID 894,请稍候…

deBUGging器成功连接。

检测到服务器编译

JVM版本是20.4-b02

遍历堆。 可能还要等一下…

使用Printezis位查找对象大小并跳过…

使用Printezis位查找对象大小并跳过…

对象直方图:

数字#实例#字节类描述

————————————————– ————————

1:11356 1551744 * Methodklass

2:11356 1435944 * ConstMethodklass

3:914 973488 * ConstantPoolKlass

4:6717 849032 char []

5:16987 820072 * SymbolKlass

6:2305 686048 byte []

7:914 672792 * InstanceKlassKlass

8:857 650312 * ConstantPoolCacheKlass

9:5243 167776 java.lang.String

10:1046 108784 java.lang.class

11:1400 87576短[]

12:1556 84040 * System ObjArray

13:1037 64584 int []

14:103 60152 * ObjArrayKlassKlass

15:622 54736 java.lang.reflect.Method

16:1102 49760 java.lang.Object []

17:937 37480 java.util.TreeMap $ Entry

18:332 27960 java.util.HashMap $ Entry []

19:579 27792 java.nio.HeapByteBuffer

20:578 27744 java.nio.HeapCharBuffer

21:1021 24504 java.lang.StringBuilder

22:1158 24176 java.lang.class []

23:721 23072 java.util.HashMap $ Entry

24:434 20832 java.util.TreeMap

25:689 18936 java.lang.String []

26:238 17440 java.lang.reflect.Method []

27:29 16800 * MethodDataKlass

28:204 14688 java.lang.reflect.FIEld

29:330 13200 java.util.linkedHashMap $ Entry

30:264 12672 java.util.HashMap

585:1 16 java.util.linkedHashSet

586:1 16 sun.rmi.runtime.NewThreadAction $ 2

587:1 16 java.util.Hashtable $ EmptyIterator

588:1 16 java.util.Collections $ EmptySet

总计:79700 8894800

堆遍历花费了1.288秒。

GDB – “线程适用所有BT满”给空白

如何将更新同步到windows符号存储?

windbg首先连接,然后在内核deBUGging过程中卡住“DeBUGgee not connected。”消息

Visual Studio 2013专业版无法启动

Visual Studio c#远程deBUGgingclosureswindows服务

你总是可以用strace -f -p pID来查看Java进程正在做什么。 从它的外观(你不能得到没有-F的Jstack ,并且线程5548显示没有调用堆栈并且是IN_VM),看起来线程5548正在花费太多时间来做某事,或者可能处于某种无限循环。

这可能是由于内存不足造成的。 我会尝试两件事情:

通过添加JVM参数在OutOfMemory上启用自动堆转储

-XX:+ HeapDumpOnOutOfMemoryError XX:HeapDumpPath = / tmp

尝试使用JConsole连接到您的JVM,并查看是否有任何不寻常的模式

我会怀疑一个内存问题。 您可能想要使用jstat来观察进程,并在需要杀死进程的时间周围使用jmap进行堆转储。 看看jstat是否表示连续的GC。 另外,您可能需要检查一般系统的运行状况(打开文件描述符,网络等)。 内存将是最简单的,所以我强烈建议从它开始。

当进程正常运行时,通过Jstack -F(-F必须存在,它产生不同于Jstack的快照)。 线程号不是Thread.ID,而是系统号。 5548似乎是在Finalizer和RefCounter之前创建的(它们不是问题的根源),所以它应该是一个GC线程或者一个编译器。

100%可能意味着监视器中的一些错误。 Java(热点)显示器使用非常简单的自旋锁定机制来确保所有权。

当然,附上一个调试器 – GDB来检查进程到底在哪里。

线程5554可能表明你有很多的finalize方法的对象,和/或finalize方法的一些问题。 看这个可能是值得的。

我对Jstack并不熟悉,但看起来它输出的信息更少,我更熟悉的线程转储。 尝试获取线程转储可能有用: kill -QUIT java_pID 。 请注意,转储到标准输出可能是控制台或记录文件,具体取决于您的设置。

如果很难确定stdout被引导到哪里,并且假定它正在转到一个文件,那么可以使用最近修改时间来查找候选文件。 这是建议在这篇博客的评论:

你可以在根目录下运行find [2]命令,找出最近x秒内发生了什么变化。 我通常使用find来帮助我访问在过去10分钟内更改的所有日志,例如:find / var / tomcat -mmin -3 -print(打印出在/ var / tomcat下修改的所有文件分钟)。

请注意,如果您正在使用-Xrs运行JVM,这意味着SIGQUIT信号处理程序将不会被安装,您将无法使用这种方式请求线程转储。

我遇到了类似的问题,我的JBOSS jvm得到了一个无限循环,最终它得到了OutOfMemory,我不能杀死这个进程而是kill -9。 我怀疑在大多数情况下的内存问题。

以下是一些工具,您可以使用这些工具本地化消耗cpu的进程部分:

perf / oprofile ,特别是opannotate – 非常适合查看地狱代码消耗的周期

strace , gstack / gdb (正如别人所说)

systemtap功能非常强大,但是与基于ptrace的工具一样,如果你的问题不涉及系统调用,那么效率就会低很多。

总结

以上是内存溢出为你收集整理的为什么这个Java进程无法终止?全部内容,希望文章能够帮你解决为什么这个Java进程无法终止?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

© 版权声明
THE END
喜欢就支持一下吧
点赞156 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容