一、引言

很多人可能在想这么一个问题:Java有垃圾回收机制,那么还存在内存泄露吗?答案是肯定的,所谓的垃圾回收GC会自动管理内存的回收,而不需要程序员每次都手动释放内存,但是如果存在大量的临时对象在不需要使用时并没有取消对它们的引用,就会吞噬掉大量的内存,很快就会造成内存溢出。

二、Java的垃圾回收机制

Java中的对象是在堆中分配,对象的创建有2中方式:new或者反射。对象的回收是通过垃圾收集器,JVM的垃圾收集器简化了程序员的工作,但是却加重了JVM的工作,这是Java程序运行稍慢的原因之一,因为GC为了能正确释放对象,必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都要进行监控,监控对象的状态是为了更加准确、及时地释放对象,而释放对象的根本原则就是该对象不再被引用。

三、Java中的内存泄露

内存泄露的对象有以下两个特点:

① 这些对象是可达的,即在有向图中存在通路可以与其相连。

② 这些对象是无用的,即程序以后都不会再使用这些对象。

public class Stack {
private final static int MAX_ATTRIBUTE = 10;
private Object[] arr;
private int index = 0;; public void push(Object obj) {
if (index > 9)
throw new IllegalArgumentException();
arr[index] = obj;
index++;
} public Stack() {
arr = new Object[MAX_ATTRIBUTE];
} public Object pop() {
if (index < 0)
throw new IllegalArgumentException();
return arr[--index];
}
}

这个程序那里发生了内存泄露呢?如果一个栈先增长然后收缩,那么从栈中弹出来的对象将不会被当做垃圾回收,即使使用栈的程序不再引用这些对象,它们也不会被回收,因为栈内部维护这对这些对象的过期引用。

public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; //Eliminate obsolete reference
return result;
}

解决办法:只要一个元素被弹出栈,那么就将它的引用置为空,GC就会回收。

四、常见的内存泄露

① 像HashMap、Vector等静态集合类的使用最容易引起内存泄露,因为这些静态变量的生命周期与应用程序一致。

Vector<Object> vector = new Vector<Object>(10);
for (int i = 1; i < 100; i++) {
Object obj = new Object();
vector.add(obj);
obj = null;
}

把对象放入Vector中,如果仅仅释放引用本身,但Vector仍然引用该对象,那么这个对象对GC来说是不可回收的,如果要回收它,最简单的办事是将Vector对象设为null。

② 在Java程序中,我们经常要和监听器打交道,通常调用诸如addXXXListener()等方法来增加监听器,但往往忘记删除这些监听器,从而增加了内存泄漏的机会。

③ 使用连接池时,除了要显式地关闭连接,还必须显式地关闭Resultset和Statement对象。否则会造成大量的这些对象无法释放,从而引起内存泄露。

Effective Java (6) - 消除过期的对象引用的更多相关文章

  1. Effective Java 之-----消除过期的对象引用

    public class Stack { private Object[] elements; private int size = 0; private static final int DEFAU ...

  2. Effective Java 第三版——7. 消除过期的对象引用

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  3. Java 消除过期的对象引用

    内存泄漏的第一个常见来源是存在过期引用. import java.util.Arrays; import java.util.EmptyStackException; public class Sta ...

  4. 《Effective Java》 读书笔记(七)消除过期的对象引用

    大概看了一遍这个小节,其实这种感觉体验最多的应该是C/C++程序,有多杀少个new就得有多个delete. 一直以为Java就不会存在这个问题,看来是我太年轻. 感觉<Effective Jav ...

  5. Effective Java —— 消除过期的对象引用

    本文参考 本篇文章参考自<Effective Java>第三版第七条"Eliminate obsolete object references" Memory leak ...

  6. Item 6 消除过期的对象引用

    过期对象引用没有清理掉,会导致内存泄漏.对于没有用到的对象引用,可以置空,这是一种做法.而最好的做法是,把保存对象引用的变量清理掉,多用局部变量.   什么是内存泄漏? 在Java中,对象的内存空间回 ...

  7. 《Effective java》-----读书笔记

    2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己!预计在2016年要看12本书,主要涉及java基础.Spring研究.java并 ...

  8. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  9. Effective java读书笔记

    2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...

随机推荐

  1. JAR 文件格式提供了许多优势和功能

    JAR 文件格式提供了许多优势和功能,其中很多是传统的压缩格式如 ZIP 或者 RAR 所没有提供的.它们包括: 安全性 可以对 JAR 文件内容加上数字化签名.这样,能够识别签名的工具就可以有选择地 ...

  2. Python——eventlet.event

    该模块提供eventlet的事件支持,事件提供了跨 greenthread 的操作原语. 同一个事件对象既可以发出事件也可以接收(等待)事件,不同的协程共享这一个事件对象,就为不同协程之间基于事件的同 ...

  3. 让不支持MVC3的服务器/空间/虚拟主机 支持MVC3 (前提是必须支持 .net 4.0才可以)

    在有的时候,你用的VPS,服务器或者是虚拟空间可能是没有安装MVC3的,下面我们就自己来手动来让虚拟空间支持(前提是空间必须是.net 4.0的,因为MVC3是在4.0下运行) 我们先在web.con ...

  4. Dominoserver 安装

    domino安装及语言包安装 http://wenku.baidu.com/view/f473600d581b6bd97f19ea9b.html dominoserver 安装后启动配置: http: ...

  5. VVDocumenter规范注释生成器

    下载地址:https://github.com/onevcat/VVDocumenter-Xcode PS:Xcode 8.0 默认支持了,但是是关闭状态,需要在终端输入如下命令开启,然后重启 Xco ...

  6. 生成asm-offset

    因为不善于在Makefile中调用shell的相关工具,所以关于asm-offsets.h中的产生的16进制数并不知如何做到. 因此自己写了个脚本,可以生成同样的文件(再次造了轮子). 参考:http ...

  7. lua:值得看的博客资源 ...

    凯奥斯 :https://blog.csdn.net/ecidevilin/article/category/6454847 https://blog.csdn.net/qinyuanpei/arti ...

  8. todo:区块链????????

    2018年这个春节,人人都在讲btc.ico.区块链. 恶补了几天区块链的知识和文章,一总结就是:一头雾水,没有哪个vc.创业者.技术人员 讲明白区块链到底是什么,技术上如何实现,就是哪些研读过中本聪 ...

  9. Python的Beautiful Soup简单使用

    Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据 Beautiful Soup提供一些简单的.python式的函数用来处理导航.搜索.修改分析树等功能 它是一个工具箱, ...

  10. Blender 编辑模式

    1.如何进入编辑模式 可直接通过“Tab”快捷键进入编辑模式,或者选择界面底部的下拉列表: 如果想退出编辑模式,可再按下“Tab”键退出. 2.编辑选择 进入编辑状态后,我们可以通过鼠标右键来选择某个 ...