由于探查器不断崩溃(热点错误),我很难跟踪此问题。在我深入研究之前,我想知道我是否确实遇到了问题: - )
我有一些线程池通过以下方式创建:Executors.newFixedThreadPool(10);线程连接到不同的网站,有时,我拒绝连接,最终抛出异常。
当我稍后调用Future.get()来获取结果时,它将捕获ExecutionException,它包装了无法建立连接时引发的异常。
程序使用相当恒定的内存量,直到异常被抛出的时间点(当特定站点过载时,它们倾向于分批发生)。在那之后,记忆再次保持不变但处于更高的水平。
所以我的问题就是内存行为(由Unix上的“top”报告)预期,因为异常只是触发了一些事情,或者我可能有一个实际的泄漏,我需要追踪?另外当Future.get()抛出异常时除了捕获异常(比如调用Future.cancel()之外)还需要做什么呢?
编辑:所以我用一些工具做了一个故事,从Java的角度来看,内存泄漏没有任何意义。我会玩一些其他生存了很长时间的代码并在一段时间后抛出异常并查看“top”报告的内存是否也会增加。好像它可能只是某种古怪。
答案 0 :(得分:1)
您的Java进程是否实际上以java.lang.OutOfMemoryError异常退出?如果没有,你不太可能有泄漏。当然,您始终可以使用JConsole附加到Java进程,捕获堆转储,并使用HPjmeter等免费工具打开它,以便快速找到。
答案 1 :(得分:0)
JVM将从堆的Xms amout开始,然后从系统中获取更多,直到Xmx。即使GC在JVM中释放堆,java进程仍然保持它从操作系统中获取的堆(因此在top
中,它似乎永远不会收缩)(使用Sun JVM(Java1.5 / 6)的经验)在Redhat Linux上)。
堆很可能被释放并且可用,但是它没有发布到操作系统,而top
java似乎使用了很多堆。
您可以使用JDK附带的visualvm工具。只需运行您的应用。在较长时间内,连接工具并查看堆遥测。如果它逐渐增长,则可能是内存泄漏。您还可以使用此工具进行堆转储,并查看正在累积的对象。