概述
java的JVM引入了垃圾回收机制,垃圾回收器会自动回收不再使用的对象,对于回收对象而言,首先要明确哪些对象可以回收,以及哪些对象不能回收,具体的方法有引用计数法和可达性分析法。由于代码的实现不同就会出现各种各样的内存泄漏问题,内存泄漏的实质就是本应该回收的对象因种种原因被JVM认为是不可回收的,因此就继续占用内存,导致可用的内存越来越少,直到内存溢出。
通过本文来总结下导致内存泄漏的常见情况以及内存泄漏的排查方式。
内存泄漏的情况
静态集合类
java中提供种类丰富的集合容器对象,如HashMap、LinkedList等,如果这些容器为静态的,那么它们的生命周期与类一致,而java中类是很难被回收的,因此容器在类被回收前将不能被释放,从而导致内存泄漏。这种情况用一句话概括就是:长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象不再使用,但是因为长生命周期的对象依赖它导致不能被回收。
变量不合理的作用域
一般而言,一个变量的作用范围大于其使用范围,那么很有可能会造成内存泄漏。
内部类持有外部类
如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。这种情况可以抽象地看成一种衔尾图。
各种连接资源
程序中会运用到各种资源,比如数据库连接、网络连接、IO连接等。这些连接资源都是要耗费内存资源的,因此当不需要使用的时候一定要关闭连接资源,如果没有关闭,这些连接就会一直占用资源,导致内存泄漏。
内存泄漏分析工具
主要还是利用jdk提供的那些工具,比如jmap、jhat等,先获取heap dump,然后利用转储分析工具分析dump文件。