Java的内存泄露问题

时间:2022-11-28 17:27:38

Java内存泄露

  记得上次去XX公司面试,一个面试官问我Java有没有内存泄露,我说有,但接下来我一下子愣了,面试官立刻很肯定地给我纠正,Java是没有内存泄露的情况,我不敢再辩了,我知道当时的情况,这也是毫无疑义的。回来之后我再查了下资料,整理了一下,内存泄露的几种情况,免得走向误区,现在给大家分享下吧  

  Java和C++中一个很大的区别就是Java有垃圾回收机制GC自动管理内存的回收,因此开发人员不需要调用方法来释放内存,而C++没有自动回收内存的机制,所以处处都需要留意内存的回收情况,万一不注意就可能出现内存泄露的情况。

  但这是不是就表明Java就没有内存泄露的问题呢?答案是否定的,也有些情况也会导致Java编写的程序出现内存泄露的问题。

Java内存回收机制

  不论哪种语言的内存分配方式,都需要返回所分配内存的其实地址,也就是返回一个指针到内存块的首地址。Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的。GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题。在Java语言中,判断一个内存空间是否符合垃圾收集标准有两个:一个是给对象赋予了空值null,以下再没有调用过,另一个是给对象赋予了新值,这样重新分配了内存空间。

Java内存泄露的原因

1、静态集合类像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector等应用着。

2、内部类和外部类的引用容易出现内存泄露的问题

3、监听器的使用,java中往往会使用到监听器,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。

4、大量临时变量的使用,没有及时将对象设置为null也可能导致内存的泄露

5、数据库的连接没有关闭情况,包括连接池方法连接数据库,如果没有关闭ResultSet等也都可能出现内存泄露的问题。

举例一个内存泄露的例子:

Vector v = new Vector(10);

for (int i = 1; i<100; i++){

    Object o = new Object();

    v.add(o);

    o = null;

}

别以为o对象被回收了,实际上v引用了这些对象,还被引用的对象GC是没有办法回收的,这样就很可能导致内存的泄露。

哪里分析错或者需要补充的地方,希望得到指点,谢谢