内存泄漏 memory leak
程序在申请内存之后,无法及时释放无用的对象所占用的内存,造成内存资源浪费
内存溢出 out of memory
程序在申请内存时,没有足够的空间供其使用
一次内存泄漏的危害可以忽略,但是内存泄漏的累积会导致内存溢出
内存泄漏的根本原因
一个对象本该被回收,但是,由于另一个还在使用中的对象持有它的引用,导致本该回收的对象不能被回收
长生命周期的对象持有短生命周期对象的引用,当短生命周期的对象不再需要时,由于长生命周期的对象持有其引用,导致无用的段对象所占用的内存无法释放
内存泄漏存在于堆内存中
(1)使用静态集合类引起内存泄漏
静态变量的生命周期和应用程序的声明周期一样,如果往静态集合类对象中添加了其它对象的引用,程序运行过程中,可能集合类中的对象已经没用了,但是,由于静态集合类一直持有对象的引用,导致内存泄漏
(2)集合中的对象的属性被修改之后,再调用集合的remove方法,不能删除,在添加同一对象可以添加成功
那个删除不掉的对象会造成内存泄漏
(3)在删除对象的时候,没有删除对象上的监听器,导致内存泄漏
(4)各种连接没有及时关闭导致内存泄漏
对于数据库连接,在没有使用数据库连接池时,关闭Connection对象时,与之关联的Statement和ResultSet对象会置为null,可以被回收
使用了数据库连接池之后,必须显式关闭三个对象
在finally代码块中,显示调用各种连接对象的close方法
(5)不正确使用单例模式导致内存泄漏
单例模式在创建类的唯一实例之后,由于这个实例是以静态变量的形式存在,因此,初始化之后,它将在JVM的整个生命周期存在
如果单例对象持有外部对象的引用,那么外部对象将不能被回收
(6) 非静态内部类创建静态实例造成内存泄漏
非静态内部类会持有外部类的引用,创建非静态内部类的静态实例之后,该静态实例的生命周期和应用程序一样长,这样,非静态内部类的静态实例就一直持有外部类的引用,从而导致外部类占用的内存不能被释放