当前位置: 首页 > 图灵资讯 > java面试题> JVM高频面试题-内存泄漏可能由哪些原因导致呢?

JVM高频面试题-内存泄漏可能由哪些原因导致呢?

来源:图灵教育
时间:2023-11-10 10:00:10
 

内存泄漏可能由哪些原因导致呢?

 

内存泄漏可能的原因有很多种:

内存泄漏可能原因

静态集合类引起内存泄漏

静态集合的生命周期和 JVM 一致,所以静态集合引用的对象不能被释放。

public class OOM {
    static List list = new ArrayList();

    public void oomTests(){
        Object obj = new Object();

        list.add(obj);
    }
}

单例模式

和上面的例子原理类似,单例对象在初始化后会以静态变量的方式在 JVM 的整个生命周期中存在。如果单例对象持有外部的引用,那么这个外部对象将不能被 GC 回收,导致内存泄漏。

数据连接、IO、Socket等连接

创建的连接不再使用时,需要调用 close 方法关闭连接,只有连接被关闭后,GC 才会回收对应的对象(Connection,Statement,ResultSet,Session)。忘记关闭这些资源会导致持续占有内存,无法被 GC 回收。

try {
            Connection conn = null;
            Class.forName("com.MySQL.jdbc.Driver");
            conn = DriverManager.getConnection("url", "", "");
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("....");
          } catch (Exception e) { 
           
          }finally {
            //不关闭连接
          }
        }

变量不合理的作用域

一个变量的定义作用域大于其使用范围,很可能存在内存泄漏;或不再使用对象没有及时将对象设置为 null,很可能导致内存泄漏的发生。

public class Simple {
    Object object;
    public void method1(){
        object = new Object();
        //...其他代码
        //由于作用域原因,method1执行完成之后,object 对象所分配的内存不会马上释放
        object = null;
    }
}

hash值发生变化

对象Hash值改变,使用HashMap、HashSet等容器中时候,由于对象修改之后的Hah值和存储进容器时的Hash值不同,所以无法找到存入的对象,自然也无法单独删除了,这也会造成内存泄漏。说句题外话,这也是为什么string类型被设置成了不可变类型。

ThreadLocal使用不当

ThreadLocal的弱引用导致内存泄漏也是个老生常谈的话题了,使用完ThreadLocal一定要记得使用remove方法来进行清除。