【问题标题】:DestroyJavaVM thread ALWAYS runningDestroyJavaVM 线程总是在运行
【发布时间】:2016-03-29 17:54:30
【问题描述】:

在分析我的应用程序时,我遇到了一个奇怪的行为 - DestroyJavaVM 线程始终在运行 - 100% 的时间。

在对该主题进行了一些研究之后,网上几乎没有任何有价值的信息,我只知道这个帖子应该是unload the JVM upon exit

如果是这样,为什么从我启动应用程序的第一刻起,这个线程就 100% 处于 RUNNING 状态?它不会消耗宝贵的资源,因此可能会导致OutOfMemoryError(就像我有时会得到的那样)?

对于这个线程实际做什么以及触发它的初始化有什么官方参考?

谢谢

【问题讨论】:

  • 其他线程更有可能导致OOME。我不会从最不明显的嫌疑人开始。您是否分析过您的应用程序线程以供内存使用?这将是调试您神秘的OOMEs 的直接方法。
  • 10 倍的答案。当然,我使用其他措施来找出为什么我得到 OOME(顺便说一句,这是一个“GC Overhead Limit Exceeded”错误,这是由 CPU 使用率高引起的),但无济于事。这是我最后的手段。这个线程非常可疑,我想知道它 100% 的时间都在运行什么业务。

标签: java multithreading jvm java-threads


【解决方案1】:

这是因为大多数应用程序都是在线程中运行的。

所有POJO 应用程序都从调用main 方法开始。在最简单的情况下,此方法将完成所有工作,创建对象、调用方法等。一旦main 完成,JVM 被告知使用一个等待所有non-daemon threads 完成的DestroyJavaVM 线程关闭在做它的工作之前。这是为了确保您创建的任何非守护线程在 JVM 被拆除之前运行完成。

但是,带有 GUI 的应用程序通常作为多个线程运行。一种用于监视系统事件,例如键盘或鼠标事件。用于维护窗口和显示等。这种应用程序的main 方法可能只会启动所有需要的线程并退出。它仍然会创建 DestroyJavaVM 线程,但现在它所做的只是等待您创建的所有线程完成,然后再拆除 VM。

因此,任何创建线程并仅依赖其功能的应用程序将始终有一个 DestroyJavaVM 线程等待它完成。由于它所做的只是joining 所有其他正在运行的线程,它不会消耗任何资源。

【讨论】:

  • 10 倍的答案。我的应用程序没有任何 GUI。不过,我正在实例化很多线程,并且肯定依赖于它们的功能。它与 DestroyJavaVM 线程有什么关系吗?实际上是什么触发了它的初始化?如果我理解正确,您说即使线程显示为 RUNNING,它实际上是 WAITING?
  • @KidCrippler - 在main 退出后创建并启动。请参阅 Thread.join() 了解为什么它处于 Running 状态 - 它在紧密循环中使用 wait(0)
【解决方案2】:

这几乎没有划伤表面。它有助于识别存在系统触发的退出和强制退出,并且应用程序必须知道如何响应 不会被非守护线程无限期阻塞。

作为一名 Java 程序员,我需要知道操作系统何时通知应用程序关闭(以便我可以保存用户的工作)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 2011-08-11
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多