【问题标题】:Why Java process hang?为什么Java进程挂起?
【发布时间】:2011-05-17 19:53:49
【问题描述】:

我的 Java 服务器中有很多线程。 当一个线程无限地递归调用一个方法时,它会挂起。 该方法被调用54次后,进程挂起,并且没有像“StackOverFlow”或“OutOfMemory”这样的日志。

但是,据我所知,只有出现问题的线程会崩溃,其他线程可以正常工作。

环境:

Linux 版本 2.6.31-20-server (buildd@crested) (gcc 版本 4.4.1 (Ubuntu 4.4.1-4ubuntu8))java版本 “1.6.0_18”Java(TM) SE 运行时 环境(构建 1.6.0_18-b07)Java HotSpot(TM) 64 位服务器虚拟机(构建 16.0-b13,混合模式)

【问题讨论】:

  • Erm...您几乎已经回答了您的问题?您处于调用递归方法的无限循环中。您的问题到底是什么?
  • "当一个线程递归调用一个方法时,它会挂起。"是的,这就是它挂起的原因。那你为什么要问它为什么挂起?我们不是通灵者;我们看不到该线程的代码,因此除非您显示代码,否则我们无法帮助您修复无限递归。

标签: java stack-overflow


【解决方案1】:

请求线程转储以查看您的线程在做什么。为您派生的每个线程设置名称以正确识别它们。我想在对象监视器上也可能有一个dead lock。我建议使用JProfiler 来查找threads are blocked on 的对象。

另一方面,无限递归并不是那么好。避免这种情况,或者为它定义限制。

【讨论】:

    【解决方案2】:

    你已经回答了你的问题:

    当一个线程递归时挂起 无限调用方法。

    我的建议是不要无限调用方法,因为递归调用方法时会非常快速地扩展堆栈。

    你想用线程做什么?您能否优化您的代码以在没有无限循环的情况下调用该方法?

    【讨论】:

      【解决方案3】:

      生成一个线程转储,它将向您显示 VM 中每个 Java 线程的堆栈跟踪。这将告诉您当 JVM 挂起时线程在做什么。

      要生成线程转储,在 UNIX 平台上,您可以使用命令 kill -QUIT process_id,其中 process_id 是您的 Java 程序的进程 ID。

      在 Windows 上,您可以在启动 Java 程序的窗口中输入按键序列<ctrl><break>。发送此信号指示 JVM 中的信号处理程序,以递归方式打印出有关 JVM 内部线程和监视器的所有信息。

      【讨论】:

        【解决方案4】:

        所有线程都需要堆栈空间。每次你递归调用一个方法时,堆栈都会扩展——最终你会用完。

        您管理的迭代次数取决于正在运行的确切代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-10
          相关资源
          最近更新 更多