对于JAVA应用程序,我有点新手,但是他参与开发了一个需要多线程的相当复杂的JAVA(8)应用程序。我自己和另一个开发人员一直遇到一个问题,即运行一段时间后应用程序内存不足。
起初我们给应用程序提供了64GB的内存,但几个小时之后就会耗尽内存,崩溃并重新启动。只是一遍又一遍地做。上下文;应用程序从消息传递系统(ActiveMQ)获取消息,并且消息的元素必须通过调用值的各种数据源来构建XML文件。可能有数百万条消息需要处理,因此我们开发了一个多线程系统,每个线程处理一条消息 - 并为应用程序提供40个线程。
然而,随着它不断收集消息,整体内存消耗随着时间的推移而上升和下降。我觉得我们没有正确使用垃圾收集器吗?
所以目前我们有一个父线程:
(new Thread(new ReportMessageConsumer(config, ""))).start();
然后在ReportMessageConsumer中我们设置了X个线程,因此在我们当前的设置中这将是40。所以这将属于这一组。一旦构建了XML并完成了线程,我们如何有效地杀死线程并强制垃圾收集器释放内存,以便我们可以创建一个新的干净线程来获取另一条消息?
答案 0 :(得分:4)
我觉得我们没有正确使用垃圾收集器?
这不是问题。你能做的最好的事情就是让GC做到没有任何干扰。不要试图强制GC运行。它很少有用,而且通常对性能不利。
真正的问题是你有内存泄漏。它可能正在发生,因为你获得越来越多的线程......或者它可能是其他东西。
我会推荐以下内容:
重写您的代码,以便它使用ExecutorService
来管理有界线程池,以及在这些线程上运行的任务队列。查看javadocs以获取一个简单示例。
使用线程池可能来提高应用程序的整体性能。在Java中创建一个线程(即Thread.start()
)相当昂贵。
(并且不要关闭池以确保完成一批工作。这对性能有害。这样做的简单方法是使用invokeAll
提交批处理;请参阅ExecutorService, how to wait for all tasks to finish)。
如果这不能解决您的泄漏问题,请使用内存分析工具来了解应用程序泄漏内存的方式/原因。有很多StackOverflow Q& A关于如何做到这一点。例如: