所有这些默认线程都应该运行吗?他们让我的JVM活着吗?

mdm*_*mdm 8 java multithreading memory-management

我有一个关于我的应用程序在执行过程中产生的线程及其状态的问题.

我有一个Swing应用程序,我注意到在一些测试场景中使用Java VisualVM有几个奇怪的行为.运行我的程序30分钟不做任何事情(刚开始并让它继续运行)我注意到以下内容.

首先,在Threads选项卡中,我看到很多活动线程. 我的申请在30分钟左右没有做任何事情的情况

读取(除其他外) 默认线程,如DestroyJavaVM,Reference Handler,Signal Dispatcher以及Java应用程序开始执行时spwaned的这些线程是什么?我理解大多数这些主题都有很好的理由去那里.(我仍然试图弄清楚"RMI TCP")但
我对他们的状态有疑问.前六个人100%处于跑步状态是否正常?

此外,这些线程中的任何一个都能解释如下所示的堆消耗吗? 我的应用程序的堆消耗什么都不做,超过30分钟

我注意到很多HashMap $ Entry和TreeMap $ Entry的实例都是由源自sun.rmi.*的库引用和创建的,我认为它可能与"RMI TCP"线程相关...

最后但并非最不重要的,如果我尝试dispose()我的主JFrame,框架本身将消失,但应用程序仍将运行....这些线程可能是原因(或其中的一部分)?

谢谢大家.

Tom*_*icz 8

我仍在试图找出"RMI TCP"

这些线程用于通过RMI接受和处理JMX连接.在查看JVisualVM时,您正在使用一个.您是否注意到工作线程名称中的IP?

但是我对他们的状态表示怀疑.前六个人100%处于跑步状态是否正常?

仅仅因为线程是可运行的,并不意味着它正在运行并消耗CPU时间.引用Thread.State:

  • - 尚未启动的线程处于此状态.

  • RUNNABLE - 在Java虚拟机中执行的线程处于此状态.

  • BLOCKED - 阻塞等待监视器锁定的线程处于此状态.

  • WAITING - 一个无限期等待另一个线程执行特定操作的线程处于此状态.

  • TIMED_WAITING - 正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态.

  • TERMINATED - 已退出的线程处于此状态.

正如您所看到的,此列表未提及有关等待I/O(如套接字)的信息.执行此任务的线程仍标记为可运行.显然等待数据不会占用任何CPU.接受连接的线程也是可运行的,而它什么都不做.当客户端尝试建立新连接时,它将被唤醒.

此外,这些线程中的任何一个都能解释如下所示的堆消耗吗?

你的堆消耗是正常和健康的.锯齿形状是由垃圾收集去除不再需要的物体引起的.JVM还发现你的堆消耗非常不变,所以它不断减少最大堆大小,因为它认为你不需要那么多(橙色图).

最后但并非最不重要的,如果我尝试dispose()我的主JFrame,框架本身将消失,但应用程序仍将运行....这些线程可能是原因(或其中的一部分)?

那是因为你只关闭了一个JFrame,而不是整个应用程序.Swing EDT(事件调度线程)仍在运行.但这与它无关.只需使用:

jFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
Run Code Online (Sandbox Code Playgroud)

在你的主框架上.

TL; DR

如果考虑线程和内存消耗,您的应用程序是完全正常的.别担心!

也可以看看

  • 为组织良好的答案+1!关于JFrame,我知道我可以使用EXIT_ON_CLOSE但是应用程序可以通过更大的框架调用,如果我只使用EXIT_ON_CLOSE,我会杀死整个JVM实例.最后一个可显示框架上的dispose()应该杀死应用程序,对吧? (2认同)