2010-03-12 130 views
2

由于探查器不断崩溃(热点错误),我很难跟踪此事。在我深入研究之前,我想知道我是否真的有问题:-)ExecutorService内存泄漏异常

我有几个线程池通过创建:Executors.newFixedThreadPool(10);这些线程连接到不同的网站,有时,我会拒绝连接,并抛出异常。

当我稍后调用Future.get()来获取结果时,它将捕获包装在无法建立连接时引发的异常的ExecutionException。

该程序使用相当不变的内存量,直到抛出异常的时间点(它们倾向于在特定站点过载时分批发生)。在此之后,记忆再次保持不变,但处于更高水平。

所以我的问题是大概是内存行为(由Unix上的“top”报告),因为异常只是触发了一些东西,或者我可能有一个实际的泄漏,我需要追踪?另外当Future.get()抛出一个异常时,除了捕获异常(比如调用Future.cancel())之外,还有什么需要做的吗?

编辑:所以我确实使用了几个工具来看看,从Java的角度来看没有任何内存泄漏明智。我会玩弄其他一些长期存在的代码,并在一段时间后引发异常,并查看“top”报告的内存是否也会增加。似乎它可能只是某种古怪。

+0

在执行程序问题上没有你的答案,我可以告诉你,top不是诊断JVM中内存问题的有用方法(查看-Xmx和-Xms选项)。在GC上的JVM中恢复的内存不一定会显示在其外(我认为它不会出现,但我不完全确定)。要检查内存使用Runtime.getRuntime()。totalMemory() - Runtime.getRuntime()。freeMemory()。 – 2010-03-12 03:51:20

回答

1

您的Java进程是否真的以java.lang.OutOfMemoryError异常退出?如果不是这样,那么它不太可能发生泄漏。当然,您可以随时使用JConsole附加到Java进程,捕获堆转储,然后使用免费工具(例如HPjmeter)打开它,以便快速找到它。

+0

它没有真正运行足够长的时间,并且内存是不变的。说“顶级”报告使用550兆,然后在一段时间后跳到750兆,并回到550兆(200来自Java)。发生异常之后,它跳到1 gig并似乎留在那里。有趣的是,即使发生了更多的异常,它仍然存在,所以想想它,也许异常会导致一些不断变化的事情发生。除了我将要使用的视觉虚拟机以外,我还会看看Jmeter。 – TofuBeer 2010-03-12 04:45:46

0

JVM将以堆的Xms开始,然后从系统中获取更多Xmx。即使GC在JVM中释放堆,java进程仍然保持它从操作系统中获取的堆(因此在top中,它永远不会缩小)(在Redhat Linux上使用Sun JVM(Java1.5/6)的经验) 。

堆可以被释放并且可用,但它不会被释放到操作系统中,并且在top中java似乎在使用大量的堆。

您可以使用visualvm,它是JDK附带的工具。运行你的应用程序。长时间连接工具并查看堆遥测。如果它不断增长,那可能是内存泄漏。你也可以使用这个工具进行堆转储,看看有哪些对象正在积累。