过多的垃圾回收线程

3
我正在使用Java开发软件,它会在接收到传感器事件时创建一个线程。这些线程的生存期非常短(<1秒)。传感器每分钟发送不超过10个事件。
这个应用程序大部分时间都运行良好,但有时会出现挂起的情况。
当我查看Eclipse调试器时,我发现有太多线程,其中大部分线程是"Thread[garbage collected]"(大约800个 @_@)。
我不知道这个bug是否是由于我的代码中动态创建线程还是其他bug引起的?

编辑:
问题确实是由创建过多的线程引起的。我已经记录了所有传感器事件的时间戳,并发现有一些点它每分钟产生大约1200个事件(该死!)。 我还编写了一个小的Java程序,尽可能地创建了许多线程。在第~4100个线程(好木头电脑)时, JVM崩溃了。它没有像我的应用程序那样挂起 :-?。 因此,我认为可能存在动态创建线程时出现罕见条件,并导致垃圾回收线程挂起的情况?

为什么要使用Dropbox而不是简单的图像上传? 在工作中,我们没有访问Dropbox的权限。 - Ajinkya
1
@Karna:只有在达到一定的声望值后,才能上传问题的图片。 - Aaron Digulla
如果您在Eclipse中运行测试,有可能会出现一些线程在失败的测试运行结束后仍然存在,因此这些线程是从之前的测试运行中遗留下来的。您是否非常小心地将除测试运行器线程以外的所有线程都设置为守护线程? - Mike Samuel
2个回答

11
不要为每个接收到的事件创建新线程。相反,使用java.util.concurrent包中的类。

创建一个ExecutorService(使用Executors类中的静态方法之一),并将处理事件的工作提交给ExecutorServiceExecutorService是一个管理您的线程池的服务。


2
线程池绝对是这里的未来方向,它们响应更快,并防止由于堆栈所需的大量分配而引起的本地(离开Java堆)碎片化。 - hardillb
是的,线程池对于这个任务来说更好,但为什么创建许多线程会失败? - Mikita Belahlazau
1
谢谢你的回答,我已经使用Executors.newCachedThreadPool()重写了代码。我会让它运行一天,希望能够成功 :) - chicken soup

1
我在NetBeans中遇到了类似的问题。一段时间后,程序会挂起,有很多(可能500个)暂停的线程。然而,在调试器之外运行时,它正常工作。我认为在运行外部时,最多只有几百个线程同时运行,但程序确实倾向于以狂热的速度启动它们。我的怀疑是调试器从未关闭线程,并且只能处理有限数量的线程。

到目前为止,我的经验是JVM非常好地处理大量快速启动和停止的线程,但NetBeans调试器(几个版本之前,其中一个是6.x)不行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接