java内存泄露

来源:互联网 发布:安徽八度网络 编辑:程序博客网 时间:2024/06/17 12:37

说到内存泄露,很多人都不是特别明白是什么概念,还有很多人把它和oom混淆了,oom是out of memory 内存溢出,和内存泄露并不是同一个概念。内存泄露可能导致内存溢出。内存泄露的定义是:内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏。

C++中的内存需要程序员手动释放与分配,而Java中有着内存回收机制,是不是就意味着没有内存泄露的问题呢,答案是否定。想要了解Java内存泄露首先要了解一下java的内存回收机制:

Java中对内存对象的访问,使用的是引用的方式。在 Java 代码中我们维护一个内存对象的引用变量,通过这个引用变量的值,我们可以访问到对应的内存地址中的内存对象空间。在 Java 程序中,这个引用变量本身既可以存放堆内存中,又可以放在代码栈的内存中(与基本数据类型相同)。 GC 线程会从代码栈中的引用变量开始跟踪,从而判定哪些内存是正在使用的。如果 GC 线程通过这种方式,无法跟踪到某一块堆内存,那么 GC 就认为这块内存将不再使用了(因为代码中已经无法访问这块内存了)。
通过这种有向图的内存管理方式,当一个内存对象失去了所有的引用之后,GC 就可以将其回收。反过来说,如果这个对象还存在引用,那么它将不会被 GC 回收,哪怕是 Java 虚拟机抛出 OutOfMemoryError 。

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设置成null希望他可以被GC回收,但是由于Vector持有了他的引用所以,o是无法被回收的,我们想要释放o的内存除了要把v设置成null还需要在vector中手动的remove掉他。

这是我自己关于java内存泄露的一些看法,如果有不对的地方欢迎大家指正,另外过两天我会在写一个关于安卓中内存泄露博客。

0 0
原创粉丝点击