java最明显的一个优势就是它的内存管理机制。你只需简单创建对象,java的垃圾回收机制负责分配和释放内存。然而情况并不像想像的那么简单,因为在Java应用中经常发生内存泄漏。

本教程演示了什么是内存泄漏,为什么会发生内存泄漏以及如何预防内存泄漏。

什么是内存泄漏?

定义:如果对象在应用中不再被使用,但由于它们在其他地方被引用,垃圾回收却不能移除它们(这样就造成了很多内存不能释放,从而导致内存溢出的现象。译注)。

要理解这一定义,我们需要理解内存中对象的状态。下图说明了那些是未使用,那些是未引用。

从图中可以看到被引用对象和未引用对象(的范围)。未引用对象可以被垃圾回收机制回收,而被引用对象不能被垃圾回收机制回收。未引用对象当然是没有使用的,因为没有其他对象引用了它。然而未使用对象并不都是未引用的。某些未使用的对象仍然被其他地方引用!这就是内存泄漏起因。

为什么会发生内存泄漏?

让我们来下面的这个例子,看看为什么会发生内存泄漏。在如下例子中,A对象引用了B对象。A的生命周期(t1-t4)比B的生命周期(t2-t3)要长的多,当B不再在应用中被使用,A仍然持有对B的引用。这样一来,垃圾回收机制不能从内存中移除B。这很有可能导致内存溢出问题,因为如果其他很多对象像A一样,那么内存中将会有很多不能被回收的对象,这将消耗大量内存空间。

也有可能的情况是B持有了大量对其他对象的引用。这些被B引用的对象同样不会被回收掉。所有这些未使用的对象将会消耗宝贵的内存空间。

如何预防内存泄漏?

如下是一些预防内存泄漏的快速技巧:

1、留意集合类,比如HashMap,ArrayList等等,因为他们是内存泄漏经常发生的地方。当它们被声明为静态对象时,他们的生命周期就和应用的生命周期一样长。

2、留意事件监听器和回调。如果一个类注册了监听器,但当该类不再被使用后没有注销监听器,可能会发生内存泄漏。

3、“如果一个类管理自己的内存,程序员应该警惕内存泄漏。”[1],很多时候对象中的指向其他对象成员变量需要设置成null(才能被回收)。

一个小测验:为什么JDK6中的substring()方法会引发内存泄漏?

要回答这个问题,你可能需要查看JDK6和7中substring()的源码。

参考文献:
1. Bloch, Joshua. Effective java. Addison-Wesley Professional, 2008.
2. IBM Developer Work. http://www.ibm.com/developerworks/library/j-leaks/

Java提高篇—— 简单介绍Java 的内存泄漏的更多相关文章

  1. Java提高篇之理解java的三大特性——继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  2. 【转】java提高篇(二)-----理解java的三大特性之继承

    [转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in ja ...

  3. java提高篇(四)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  4. java提高篇(二)-----理解java的三大特性之继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  5. (转)java提高篇(二)-----理解java的三大特性之继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  6. java提高篇之理解java的三大特性——多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  7. (转)java提高篇(四)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  8. java提高篇-----详解java的四舍五入与保留位

    转载:http://blog.csdn.net/chenssy/article/details/12719811 四舍五入是我们小学的数学问题,这个问题对于我们程序猿来说就类似于1到10的加减乘除那么 ...

  9. 【转】java提高篇之理解java的三大特性——多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

随机推荐

  1. Asp.Net MVC4 + Oracle + EasyUI 学习 第二章

    Asp.Net MVC4 + Oracle + EasyUI 第二章 --使用Ajax提升网站性能 本文链接:http://www.cnblogs.com/likeli/p/4236723.html ...

  2. NSURLConnection 异步加载网络数据

    #import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...

  3. Java基础知识点2:hashCode()方法

    hashCode()方法基本实现 hashCode方法是Java的Object类所定义的几个基本方法之一.我们可以深入到Object类的源码中去查看: public native int hashCo ...

  4. npm-bluebird使用

    API 注意 时刻注意return; 使用Promise.promisify简化对test(val, function(err, result){})的处理; 尽量避免使用deferred objec ...

  5. input的实时监控

    <input id="phone" type="tel" placeholder="请输入手机号"> $("#phon ...

  6. BZOJ 3157 &数学乱搞...

    挖一发坑...一碰到数学题头晕眼花...看着证明感觉我幼儿园还没毕业... http://www.cnblogs.com/zhuohan123/p/3726933.html 等我会完完整整地写一发la ...

  7. 基于FS4412的DS18B20温度采集编程实现(1-时序分析)

    作者:秦老师,华清远见嵌入式学院讲师. 一.DS18B20简介 DS18B20是常用的数字温度计.DS18B20数字温度计提供9至12位(可配置)温度读数,表明该设备的温度. 信息通过单总线接口被发送 ...

  8. 记一次windows下物理迁移数据库的过程

    背景:      最近因为一次设备故障,导致一台运行windows环境下的机器无法启动,里面有一个正在使用的财务数据库,该数据库也只是每月使用一次,需要把物理数据迁移出来,于是拔出了故障机器的硬盘,通 ...

  9. 使用CallableStatement的用法

    package Test; import java.sql.*; public class Test7 { public static void main(String[] args) { Conne ...

  10. SQL语法

    full outer--全连.两表相同的组合在一起,A表有,B表没有的数据(显示为null),同样B表有,A表没有的显示为(null) A表 left join B表--左连,以A表为基础,A表的全部 ...