首页 > 代码库 > 第6条:消除过期对象的引用
第6条:消除过期对象的引用
让咱们先来看一下数组实现栈的例子:
package chaper1; import java.util.Arrays; import java.util.EmptyStackException; public class Stack_Test00 { private Object[] elements; private static int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack_Test00(){ 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]; } /** * 每次栈中元素已满时,将栈的容量扩大一倍 */ private void ensureCapacity(){ if(elements.length == size){ elements = Arrays.copyOf(elements, 2 * size); } } }
表面上看起这段代码并没有任何的错误之处,但是随着垃圾回收器活动的增加,或者由于占用内存的不断增加,程序性能的降低会逐渐表现出来。在极端情况下,这种内存泄露会导致磁盘交换(Disk Paging),甚至导致程序失败(OutOfMemoryError错误),但是这种失败情形相对比较少见。
而这段内存代码内存泄露的主要原因在于,一个栈在先增长后收缩,那么战中pop出来的元素不会被当作垃圾回收,及时程序不再对其进行引用。
这是因为:栈内部维护着对这些对象的过期引用(obsolete reference)。而所谓的过期引用就是指永远也不会被解除引用,不会解除引用则不能够被回收。
为了消除这种过期引用最好的方法就是再它无效的时候,将其置为null。
public Object pop(){ if(size == 0) throw new EmptyStackException(); Object result = elements[--size]; elements[size] = null; return result; }
但是,我们要知道将对象置为空只是一种手段,而不是规范。
消除引用的最好方法还是应该让包含改变量的引用结束其生命周期,最佳的方式就是在最紧凑的作用域范围内定义每一个变量。
———————————————————————————————————————————————————————————————————————————————
上面例子中内存泄露的最主要原因就是该类自己管理管理内存。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。