JAVA多线程,内存泄漏,垃圾收集器

时间:2016-06-30 12:55:06

标签: java multithreading garbage-collection

对于JAVA应用程序,我有点新手,但是他参与开发了一个需要多线程的相当复杂的JAVA(8)应用程序。我自己和另一个开发人员一直遇到一个问题,即运行一段时间后应用程序内存不足。

起初我们给应用程序提供了64GB的内存,但几个小时之后就会耗尽内存,崩溃并重新启动。只是一遍又一遍地做。上下文;应用程序从消息传递系统(ActiveMQ)获取消息,并且消息的元素必须通过调用值的各种数据源来构建XML文件。可能有数百万条消息需要处理,因此我们开发了一个多线程系统,每个线程处理一条消息 - 并为应用程序提供40个线程。

然而,随着它不断收集消息,整体内存消耗随着时间的推移而上升和下降。我觉得我们没有正确使用垃圾收集器吗?

所以目前我们有一个父线程:

(new Thread(new ReportMessageConsumer(config, ""))).start();

然后在ReportMessageConsumer中我们设置了X个线程,因此在我们当前的设置中这将是40。所以这将属于这一组。一旦构建了XML并完成了线程,我们如何有效地杀死线程并强制垃圾收集器释放内存,以便我们可以创建一个新的干净线程来获取另一条消息?

1 个答案:

答案 0 :(得分:4)

  

我觉得我们没有正确使用垃圾收集器?

这不是问题。你能做的最好的事情就是让GC做到没有任何干扰。不要试图强制GC运行。它很少有用,而且通常对性能不利

真正的问题是你有内存泄漏。它可能正在发生,因为你获得越来越多的线程......或者它可能是其他东西。

我会推荐以下内容:

  1. 重写您的代码,以便它使用ExecutorService来管理有界线程池,以及在这些线程上运行的任务队列。查看javadocs以获取一个简单示例。

    使用线程池可能来提高应用程序的整体性能。在Java中创建一个线程(即Thread.start())相当昂贵。

    (并且不要关闭池以确保完成一批工作。这对性能有害。这样做的简单方法是使用invokeAll提交批处理;请参阅ExecutorService, how to wait for all tasks to finish)。

  2. 如果这不能解决您的泄漏问题,请使用内存分析工具来了解应用程序泄漏内存的方式/原因。有很多StackOverflow Q& A关于如何做到这一点。例如: