一、什么是内存泄漏:

内存泄露 (memory leak)是指程序在申请内存后,无法释放已申请的内存空间。

二、Java中的内存管理

  1. Java中内存申请:
    Java程序在运行中会需要通过关键字new为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间。
  2. java中的内存释放:
    Java的一个重要优点就是通过垃圾收集器(Garbage Collection,GC)自动管理内存的回收,不需要通过调用函数来释放内存。因此,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。
  3. java中的内存管理
    Java使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的。这种方式的优点是管理内存的精度很高,但是效率较低。另外一种常用的内存管理技术是使用计数器,它与有向图相比,精度行低(很难处理循环引用的问题),但执行效率很高。
  4. Java中的内存泄漏问题
    在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
  5. 内存泄漏原因
    (1)静态集合类引起内存泄露:
    像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被Vector等引用着。
    (2)当集合里面的对象属性被修改后,再调用remove()方法时不起作用:
    (3)监听器
    在java编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。
    (4)各种连接
    比如数据库连接、网络连接(socket)和io连接,对象要调动close()方法手动释放内存。
    (5)单例模式
    不正确使用单例模式是引起内存泄漏的一个常见问题,单例对象在初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部的引用,那么这个对象将不能被JVM正常回收,导致内存泄漏。