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

 
什么是内存泄漏?
在Java中,对象的内存空间回收是由Java垃圾回收器回收的。而Java垃圾回收器判定一个对象能否被回收的依据是,该对象是否可达。如果该对象可达,则垃圾回收器不会回收该对象的内存空间,反之,则回收。垃圾回收器判定一个对象是否可达,是根据该对象的引用链来决定的。
如果没有变量持有指向该对象的引用,那么,该对象就是不可达的。那么,垃圾回收器在下次回收的时候,就可以回收该对象。
如果,依然有变量持有指向该对象的引用,但是,我们找不到该变量,那么,就称为该对象泄漏了-----垃圾回收器不可以回收该对象,因为它依然可达;但是,我们不知道如何使用该对象,因为我们找不到指向该对象的引用。
当程序中,这种情况积聚很多的时候,就会导致内存泄漏。
 
场景一:
内存泄漏,丢失了指向该对象的引用
import java.util.Arrays;
import java.util.EmptyStackException; public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() {
elements = new Object[ DEFAULT_INITIAL_CAPACITY];
} public void push(Object e) {
ensureCapacity();
elements[size++] = e;
} public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[-- size];
} /**
* Ensure space for at least one more element, roughly doubling the capacity each time the array
* needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements , 2 * size + 1);
}
}
--------------------------
问题出在这里:
  public Object pop() {
if ( size == 0)
throw new EmptyStackException();
return elements[-- size];
}
比方说,我入栈了10个元素,然后,我调用pop()方法,我调用6次pop()方法,这时,size是4,表明elemnts中还有4个元素。但是,实际上,elements还有另外6个存在,但是,这6个我们访问不到它们,但是它们是存在。这6个我们访问不到的元素,均持有指向相应对象的引用。
 
于是,就内存泄漏了----6个对象依然存在,垃圾回收器不会回收它们,因为有变量持有指向它们的引用;而我们访问不到这些变量。
 
将pop方法修改为:
  public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements [--size ];
elements[size] = null;
return result ;
}
这样,出栈的元素,在elements中不再保留出栈元素中指向对应对象的引用。
 
 
场景二:
 
“内存泄漏的另一个常见来源是缓存。一旦你把对象引用放到缓存中,它就很容易被忘掉,从而使得它不再有用之后很长一段时间内依然留在缓存中。”
 
缓存的实现。
 
使用WeakHashMap。WeakHashMap适合的场景是,如果你要缓存的项(作为Map中的项),它的生命周期(也就是说,它什么时候被删除掉)是由该项的键(K)的外部引用决定的,而不是由该项的值(Value)决定的,那么,就可以使用WeakHashMap<K,V>来实现。
 
WeakHashMap<K,V>是这么个东西,它的K是一个对象,它有相应的内容。指向K的引用时一个弱引用,当K被置空的时候,或者当内存不够用的时候,垃圾回收器会回收K对象。当K对象被回收的时候,系统也会回收该K所在的项(K,V)。也就是说,Map中的项的存活是由K对象来决定的。
 
这里要考虑的问题是,K什么时候被置空。
WeakHashMap使用的一个例子:
实现需求的需求---保存每个存活的线程的信息,然后,可以在一个地方,根据线程来查询相应的信息。当线程死掉的时候,自动将其对应的信息清除掉。
 
这里面,线程什么时候死掉,也就是什么时候为空,这个是不确定的。这个适合使用WeakHashMap<K,V>数据结构来实现。
WeakHashMap<Thread,SomeMetaData>
当线程Thread死掉了,为空了,那么系统就会自动将相应的条目从WeakHashMap<Thread,SomeMetaData>中清除掉。
 
 
场景三:
 

Item 6 消除过期的对象引用的更多相关文章

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

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

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

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

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

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

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

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

  5. Effective Java (6) - 消除过期的对象引用

    一.引言 很多人可能在想这么一个问题:Java有垃圾回收机制,那么还存在内存泄露吗?答案是肯定的,所谓的垃圾回收GC会自动管理内存的回收,而不需要程序员每次都手动释放内存,但是如果存在大量的临时对象在 ...

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

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

  7. EffectiveJava(6)消除过期对象的引用

    消除过期对象的引用 过期引用 – 在操作集合类的时候,未清理过期的对象引用(即:过期引用),常会导致内存泄露.从而报outOfmemory错误. 1.过期对象导致内存泄漏. 2.一旦对象引用过期,清除 ...

  8. Effective Java 3

    <Effective Java>作者是美国的Joshua Bloch,连Gosling都说需要看的书,讨论的是更深层次的Java开发技术,适合于有一定Java基础的人看. 这是一本分享经验 ...

  9. Effective Java 创建和销毁对象

    <Effective Java>阅读笔记,用适合自己理解的方式提炼该书内容.<Effective Java>是一本很实用的书,阅读方法应该是快速的领会,总结,然后应用.而非,一 ...

随机推荐

  1. iOS- 给App添加内购& 验证购买iOS7新特性

    1.内购——应用内购买 我所说的内购——也可以说是应用内购买 大家都知道通过苹果应用程序商店有三种主要赚钱的方式: 1.直接收费(与国内大部分用户的消费习惯相悖,如果要收费,直接收高的,别收6块钱) ...

  2. iOS开发UIColor,CGColor,CIColor三者的区别和联系

    最近看了看CoreGraphics的东西,看到关于CGColor的东西,于是就想着顺便看看UIColor,CIColor,弄清楚它们之间的区别和联系.下面我们分别看看它们三个的概念: 一.UIColo ...

  3. lol佐伊美图

      心血来潮,分享一波从各个网站上搜集到的佐伊美图,持续更新!(最近更新日期:2019/03/17) Section1 暮光星灵 2018/11/16 2019/02/15 2019/03/17 Se ...

  4. Jmeter系列-自动生成html报告

    从JMeter 3.0开始已支持自动生成动态报告,我们可以更容易根据生成的报告来完成我们的性能测试报告. 如何生成html测试报告 如果未生成结果文件(.jtl),可运行如下命令生成报告: jmete ...

  5. JXM 监控tomcat 7(含代码

    1.在tomcat的server.xml中加入: <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleL ...

  6. Go语言【第十三篇】:Go语言递归函数

    Go语言递归函数 递归,就是在运行的过程中调用自己,语法格式如下: func recursion() { recursion() /* 函数调用自身 */ } func main() { recurs ...

  7. 51nod 1385凑数字(字符串+构造)

    题目大意: 给定一个n,要求找出一个最短的字符串S,使得所有1到n的整数都是S的子序列. 比如n=10,那么S=”1234056789”的时候,是满足条件的.这个时候S的长度是10. 现在给出一个n, ...

  8. P2672 推销员 优先队列 + 贪心

    ---题面--- 题解: 我会说我想这道普及组题都想了好久么.... 不熟练的普及组选手.jpg 最后随便猜了一个结论居然是对的... 放结论: 假设x = i的最优决策为f[i], 那么f[i + ...

  9. ZOJ1994 & POJ2396:Budget——题解

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1994 http://poj.org/problem?id=2396 题目大 ...

  10. BZOJ5333:[SDOI2018]荣誉称号——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5333 https://www.luogu.org/problemnew/show/P4620 题意 ...