Effective Java (6) - 消除过期的对象引用
一、引言
很多人可能在想这么一个问题: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) - 消除过期的对象引用的更多相关文章
- Effective Java 之-----消除过期的对象引用
public class Stack { private Object[] elements; private int size = 0; private static final int DEFAU ...
- Effective Java 第三版——7. 消除过期的对象引用
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Java 消除过期的对象引用
内存泄漏的第一个常见来源是存在过期引用. import java.util.Arrays; import java.util.EmptyStackException; public class Sta ...
- 《Effective Java》 读书笔记(七)消除过期的对象引用
大概看了一遍这个小节,其实这种感觉体验最多的应该是C/C++程序,有多杀少个new就得有多个delete. 一直以为Java就不会存在这个问题,看来是我太年轻. 感觉<Effective Jav ...
- Effective Java —— 消除过期的对象引用
本文参考 本篇文章参考自<Effective Java>第三版第七条"Eliminate obsolete object references" Memory leak ...
- Item 6 消除过期的对象引用
过期对象引用没有清理掉,会导致内存泄漏.对于没有用到的对象引用,可以置空,这是一种做法.而最好的做法是,把保存对象引用的变量清理掉,多用局部变量. 什么是内存泄漏? 在Java中,对象的内存空间回 ...
- 《Effective java》-----读书笔记
2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己!预计在2016年要看12本书,主要涉及java基础.Spring研究.java并 ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- Effective java读书笔记
2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...
随机推荐
- java web 过滤器跟拦截器的区别和使用
注:文章整理自知乎大牛以及百度网友(电脑网络分类达人 吕明),特此感谢! 一.过滤器 1.什么是过滤器? 过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上.过滤器可附加到一个 ...
- 九章算法:BAT国内班 - 课程大纲
第1章 国内笔试面试风格及准备方法 --- 分享面试经验,通过例题分析国内面试的风格及准备方法 · 1) C/C++部分: 实现 memcpy 函数 STL 中 vector 的实现原理 · 2)概率 ...
- [mysql] linux下使用yum安装mysql
From: http://www.2cto.com/database/201207/141878.html linux下使用yum安装mysql 1.安装 查看有没有安装过: ...
- JSP九大内置对象与Servlet学习笔记[转]
我们常说的JSP有九大内置对象分别为:request.response.session.out.pagecontext.page.exception.application.config. 我们知道, ...
- 压缩打包介绍/gzip压缩工具/bzip2压缩工具/xz压缩工具
6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 常见的压缩文件格式 windows .rar .zip .7z linux ...
- Fragment管理工具类
Fragment相关→FragmentUtils.java→Demo addFragment : 新增fragment removeFragment : 移除fragment replaceFragm ...
- SOCKET,TCP/IP,UDP,HTTP,FTP总结
一.TCP/UDP,SOCKET,HTTP,FTP简析 TCP/IP是个协议组(主要解决数据如何在网络中传输),可分为三个层次:网络层.传输层和应用层: 网络层:IP协议.ICMP协议.ARP协议 ...
- jenkins 神奇变量
Hudson自己设置的一些环境变量可用于通过Hudson来执行shell脚本.Windows批处理文件和Ant文件,他们包括 Hudson设置环境变量 当一个Hudson作业执行时,它会设置一些环境变 ...
- Android开发学习笔记-自定义组合控件
为了能让代码能够更多的复用,故使用组合控件.下面是我正在写的项目中用到的方法. 1.先写要组合的一些需要的控件,将其封装到一个布局xml布局文件中. <?xml version="1. ...
- Hibernate session FlushMode的五种设置
http://www.2cto.com/kf/201207/141455.html Hibernate session FlushMode有五种属性:1.NEVEL:已经废弃了,被MANUAL取代了2 ...