引言:您是否碰到某个Java应用程序起初运行良好,经过一段时间后却缓慢下来了?或者它在处理少量文件时性能不错,文件量一旦增加就性能下降的情况呢?那么很可能您遇到了内存泄漏的问题。 您是否碰到某个Java应用程序起初运行良好,经过一段时间后却缓慢下来了?或者它在处理少量文件时性能不错,文件量一旦增加就性能下降的情况呢?那么很可能您遇到了内存泄漏的问题。 在应对内存泄漏时,如果有人问我:“你是否知道此事的前因后果和应对方法的?”那么,我就会做如下回答: 目标受众 尽管在一般情况下,本文中所介绍的方法是独立于IDE和操作系统的,但是我在此所用到的截图和说明仍然来自于Fedora Linux和带插件开发的Eclipse。 内存泄漏的症状 起初运行速度快,但随着时间的推移速度就慢下来了。比如说: · 能够正常处理少量数据集,但应对大量数据集时出现严重的性能问题。
·
· 在您的JVM中,旧版本(Old-Generation)内存的使用率持续增加。
·
· 在您的JVM中,出现内存耗尽的跳转错误。
·
· 无故自我崩溃。
·
常见的内存泄漏 Java中的内存泄漏通常发生在您忘记关闭某个资源,或是某个对象的引用没能释放的时候。例如: ·
· 在equals()和hashcode()不被使用时,各种哈希映射的引用仍然保持激活的状态,例如:
·
· import java.util.Map;
·
· public class MemLeak {
·
· public final String key;
·
· public MemLeak(String key) {
·
· this.key = key;
·
· }
·
· public static void main(String args[]) {
·
· try {
·
· Map map = System.getProperties();
·
· for(;;) {
·
· map.put(newMemLeak("key"), "value");
·
· }
·
· }catch(Exception e) {
·
· e.printStackTrace();
·
· }
·
· }
·
· }
·
·
·
如何一次性修复它们? 这里提供两种方法。第一种是尝试“快速修复”。如果此法失败,那么您就必须往下尝试一条漫长的解决之路了。 1)快速修复:使用Eclipse内存泄漏的警告(去捕捉一些泄漏)。 2)手动禁用和启用您代码的各个部分,并使用VisualVM(Jconsole或Thermostat)之类的工具观察JVM的内存使用情况。 1)快速修复:Eclipse内存泄漏的警告/错误。 为了遵从JDK 1.5+的代码规范,Eclipse会向您“抛出”一些明显泄漏用例的警告和错误。更精确地说,任何使用了closable(如1.5后出现的outputStream)的对象,如果它的引用是被销毁而不是封闭的话,就会抛出一个警告。然而在Eclipse的各个项目中,其检漏功能并非总是被启用的。因此,为了事先打开它们,您可以到项目的设置里,按照下图所示进行开启: 此处Eclipse罗列出了各种内存泄漏:然而,就算使用了Eclipse的此项功能,系统仍无法探测到所有的文件关闭与泄漏。尤其是在使用旧式(1.5之前)代码时,您很可能会因为它们在使用过程中仅仅只是“关闭”(closable)了,而遇到泄漏问题了。也有时候,文件在深度嵌套中被打开/关闭,也会导致Eclipse无法检测到。因此如果您碰到这种情况,就可能需要去尝试第2种方法了。