第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;
}

但是,我们要知道将对象置为空只是一种手段,而不是规范。

消除引用的最好方法还是应该让包含改变量的引用结束其生命周期,最佳的方式就是在最紧凑的作用域范围内定义每一个变量。

———————————————————————————————————————————————————————————————————————————————

上面例子中内存泄露的最主要原因就是该类自己管理管理内存。

第6条:消除过期对象的引用

时间: 2024-10-13 12:31:11

第6条:消除过期对象的引用的相关文章

第六条---消除过期的对象的引用

看下面的关于栈的程序: package com.duo.month10day25; import java.util.Arrays; import java.util.EmptyStackException; public class StackTest { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public StackTes

第7项:清除过期对象的引用

??当你从手工管理内存的语言(比如C或者C++)转换到具有垃圾回收功能的语言的时候,程序猿的工作就会变得更加容易,因为当你用完了对象之后,他们就会被自动回收.当你第一次经历对象回收功能的时候,会觉得这简直有点不可思议.这很容易给你留下这样的印象,认为自己不再需要考虑内存管理的事情了,其实不然. ??考虑下面这个简单的栈实现的例子: // Can you spot the "memory leak"? public class Stack { private Object[] eleme

第六条:消除过期的对象引用

Java的垃圾回收机制并不代表我们不需要考虑内存管理的问题. 考虑: public class Stack { pprivate Object[] elements; private int size = 0; private static final int DEFAULT_INITAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITAL_CAPACITY]; } public void push(Objec

Java对象及其引用 (1)

Java对象及其引用 [文章转载自:http://zwmf.iteye.com/blog/1738574] 说明:所有转载为个人学习存档使用,凡转载内容均注明转载出处.以后不再说明. 关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用, 那实在没法很好地理解下面的面向对象技术.把自己的一点认识写下来,或许能让初学Java的朋友们少走一点弯路. 为便于说明,我们先定

实习第二天-对象-对象引用-引用变量-精-精-精-下雨天

class Person{ } Person是一个数据类型-引用类型 数据类型-变量名   Person a;  声明一个引用类型的变量a,然后在栈中给引用变量a分配了内存空间 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用, 那实在没法很好地理解下面的面向对象技术.把自己的一点认识写下来,或许能让初学Java的朋友们少走一点弯路. 为便于说明,我们先定义一个简单的类: class Vehicl

消除过期的对象引用

本文涉及的概念 1.Java的内存泄露 2.出现Java内存泄露的几种常见场景 Java的内存泄露 Java语言,创建对象后,程序员不用手动回收对象.Java虚拟机会手动回收不使用的对象(没有引用指向该对象).那么,为什么还出现泄露.Java的内存泄露是指这样一种情况,创建一个对象,系统中依然存在引用指向该对象,该对象是可达的:但是,我们找不到该引用,或者我们没发现该引用的存在.于是,一直存在该对象,但是,它对我们不可用,Java虚拟机也不能回收该对象. “ 在Java中,内存泄漏就是存在一些被

消除临时对象

消除临时对象 在我们的代码中,有些临时对象正在使用而我们并未察觉; 性能优化时,消除临时对象,特别是大的临时对象,对提升性能效果明显: 这里列出常见的临时对象产生的地方: 按值返回 按值返回函数结果,结果就是一个临时对象 string add(string s1,string s2) { string s3; s3 = s1+s2; return s3; } 解决方案: 在大多数场景下,这个临时对象可以通过按引用返回来消除: void add(string s1,string s2,string

转发:Java对象及其引用

原文: http://zwmf.iteye.com/blog/1738574 Java对象及其引用 关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用, 那实在没法很好地理解下面的面向对象技术.把自己的一点认识写下来,或许能让初学Java的朋友们少走一点弯路. 为便于说明,我们先定义一个简单的类: class Vehicle { int passengers; i

Java对象及其引用

关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用, 那实在没法很好地理解下面的面向对象技术.把自己的一点认识写下来,或许能让初学Java的朋友们少走一点弯路. 为便于说明,我们先定义一个简单的类: class Vehicle { int passengers; int fuelcap; int mpg; } 有了这个模板,就可以用它来创建对象: Vehicle