我有一个关于我的应用程序在执行期间产生的线程及其状态的问题。
我有一个Swing应用程序,我在使用Java VisualVM的一些测试场景中注意到了一些奇怪的行为。运行我的程序30分钟不做任何事情(刚开始并让它继续运行)我注意到以下内容。
首先,在Threads选项卡中,我看到很多活着的线程。
阅读(除其他外) Default threads like, DestroyJavaVM, Reference Handler, Signal Dispatcher和What are these threads which are spwaned when a Java application begins its execution?我理解大多数这些主题都有很好的理由去那里。 (我仍在试图找出“RMI TCP”) 但是我对他们的状态表示怀疑。前六个人100%处于跑步状态是否正常?
此外,这些线程中的任何一个都可以解释如下所示的堆消耗吗?
我注意到很多HashMap $ Entry和TreeMap $ Entry的实例都是由源自sun.rmi。*的库引用和创建的,我认为它可能与“RMI TCP”线程有关...
最后但并非最不重要的是,如果我尝试dispose()我的主JFrame,框架本身将消失,但应用程序仍将运行....这些线程可能是原因(或其中的一部分)?
谢谢大家。
答案 0 :(得分:8)
我仍在试图找出“RMI TCP”的
这些线程用于通过RMI接受和处理JMX连接。在查看JVisualVM时,您正在使用一个。您是否注意到工作线程名称中的IP?
然而,我对他们的状态表示怀疑。前六个人100%处于跑步状态是否正常?
仅仅因为线程 runnable ,并不意味着正在运行并消耗CPU时间。引用Thread.State
:
NEW - 尚未启动的线程处于此状态。
RUNNABLE - 在Java虚拟机中执行的线程处于此状态。
BLOCKED - 阻止等待监视器锁定的线程处于此状态。
WAITING - 无限期等待另一个线程执行特定操作的线程处于此状态。
TIMED_WAITING - 正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态。
已终止 - 已退出的主题处于此状态。
正如您所看到的,此列表未提及有关等待I / O(如套接字)的信息。执行此任务的线程仍标记为 runnable 。显然等待数据不会占用任何CPU。接受连接的线程也是 runnable ,而它什么都不做。当客户端尝试建立新连接时,它将被唤醒。
此外,这些线程中的任何一个都可以解释堆消耗,如下所示吗?
您的堆消耗正常且健康。锯齿形状是由垃圾收集去除不再需要的物体引起的。 JVM还发现你的堆消耗非常稳定,所以它不断减少最大堆大小,因为它认为你不需要那么多(橙色图)。
最后但并非最不重要的是,如果我尝试dispose()我的主JFrame,框架本身将消失,但应用程序仍将运行....这些线程可能是原因(或其中的一部分)?
那是因为你只关闭了JFrame
,而不是整个应用程序。 Swing EDT(event dispatching thread)仍在运行。但这与它无关。只需使用:
jFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
在主框架上。
您的应用程序完全正常。别担心!