【问题标题】:Suspending the JVM for a limited amount of time在有限的时间内暂停 JVM
【发布时间】:2010-04-20 10:33:31
【问题描述】:

如何在可配置的时间内暂停 JVM 的执行,类似于在完整的串行垃圾收集上发生的事情?我想测试一些边缘情况,但很难通过手动生成垃圾 + System.gc() 来创建我需要的确切暂停。


我正在尝试“冻结”应用程序中的所有线程,以模拟应用程序无响应然后恢复执行的情况。该应用程序是集群的一部分,我正在尝试调试一些离开/加入/重新加入问题。

【问题讨论】:

  • 不确定您要做什么。一个简单的 sleep() 会起作用吗?
  • @Romain:查看我的问题更新。
  • 您最终回答了自己的问题? :) 您有没有机会从内部发现有关如何怀疑 JVM 本身的信息?我现在需要那个解决方案。 :)

标签: java jvm


【解决方案1】:

JVM 挂起可以通过命令行使用jdb

jdb -attach 8787
Initializing jdb ...
> suspend
All threads suspended.
> resume
All threads resumed.
> exit

但这要求它以-Xdebug ...开头

还有universal way可以暂停和恢复Linux/Unix上的任何进程:

kill -SIGSTOP PID
kill -SIGCONT PID

另见How to suspend/resume a process in Windows?

【讨论】:

    【解决方案2】:

    从 Eclipse 调试时,您可以暂停所有线程,我猜其他调试器也允许这样做。因此,您需要使用 JVM 调试选项启动服务器并远程连接到它。

    在我的情况下(运行 JBoss),我通过添加以下行来修改启动脚本:

    set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n %JAVA_OPTS%
    

    然后在 Eclipse 中,运行 -> 调试配置 -> 删除 Java 应用程序 -> 新建

    通常您只需要提供主机名和端口即可。

    【讨论】:

    • 谢谢,我正在考虑。你知道我如何在没有 Eclipse 的情况下做到这一点吗?
    【解决方案3】:

    使用虚拟机并完全暂停其执行。

    【讨论】:

      【解决方案4】:

      我认为您可能想要一些侵入性较小的东西,但一种方法是让一个控制线程获得一个锁,然后让所有其他线程也尝试获得那个锁。然后在放弃之前让控制线程休眠一段时间。一个稍微不那么笨拙的版本是使用一个信号量,每个线程有一个许可,然后让控制线程全部获取它们,然后让所有其他线程尝试获取许可。

      正如我所说的那样,您必须将其侵入到每个线程的代码中。

      另一种方法是在调试器下运行代码并手动挂起每个线程。

      【讨论】:

      • 感谢您的回答。我一直在寻找可以锁定所有线程的东西,包括一些由第三方代码控制的东西。
      • 稍微复杂一点的方法可能是使用 JPDA api 编写您自己的调试器,该调试器枚举线程并暂停它们。
      • 听起来很有趣。我在 jdb 中没有找到与此相关的任何内容。您对如何做到这一点有任何指示吗?
      猜你喜欢
      • 2016-10-01
      • 2011-05-26
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多