手动释放(dispose)对象空间和跟踪引用计数

来源:互联网 发布:ie加载项里面没有java 编辑:程序博客网 时间:2024/05/22 15:08

        1、由于Mouse2对象创建了其成员对象rodent2,并且知道它们应该存活多久(只要Mouse2还存活着),因此Mouse2知道何时调用dispose去释放(销毁)成员对象。
        以什么顺序去释放?
        销毁的顺序应该和初始化顺序相反。这是因为导出类的清理可能会调用基类中的某些方法,所以应该让基类中的构件仍然起作用而不应该过早的消毁。
a)对于字段,则意味着与声明的顺序相反;
b)对于基类,则首先对其导出类进行清理,然后才是基类;
例程:

//: polymorphism/Frog.java// Cleanup and inheritance.package polymorphism;import static net.mindview.util.Print.*;class Characteristic {  private String s;  Characteristic(String s) {    this.s = s;    print("Creating Characteristic " + s);  }  protected void dispose() {    print("disposing Characteristic " + s);  }}class Description {  private String s;  Description(String s) {    this.s = s;    print("Creating Description " + s);  }  protected void dispose() {    print("disposing Description " + s);  }}class LivingCreature {  private Characteristic p =    new Characteristic("is alive");  private Description t =    new Description("Basic Living Creature");  LivingCreature() {    print("LivingCreature()");  }  protected void dispose() {    print("LivingCreature dispose");    t.dispose();    p.dispose();  }}class Animal extends LivingCreature {  private Characteristic p =    new Characteristic("has heart");  private Description t =    new Description("Animal not Vegetable");  Animal() { print("Animal()"); }  protected void dispose() {    print("Animal dispose");    t.dispose();    p.dispose();    super.dispose();  }}class Amphibian extends Animal {  private Characteristic p =    new Characteristic("can live in water");  private Description t =    new Description("Both water and land");  Amphibian() {    print("Amphibian()");  }  protected void dispose() {    print("Amphibian dispose");    t.dispose();    p.dispose();    super.dispose();  }}public class Frog extends Amphibian {  private Characteristic p = new Characteristic("Croaks");  private Description t = new Description("Eats Bugs");  public Frog() { print("Frog()"); }  protected void dispose() {    print("Frog dispose");    t.dispose();    p.dispose();    super.dispose();  }  public static void main(String[] args) {    Frog frog = new Frog();    print("Bye!");    frog.dispose();  }} /* Output:Creating Characteristic is aliveCreating Description Basic Living CreatureLivingCreature()Creating Characteristic has heartCreating Description Animal not VegetableAnimal()Creating Characteristic can live in waterCreating Description Both water and landAmphibian()Creating Characteristic CroaksCreating Description Eats BugsFrog()Bye!Frog disposedisposing Description Eats Bugsdisposing Characteristic CroaksAmphibian disposedisposing Description Both water and landdisposing Characteristic can live in waterAnimal disposedisposing Description Animal not Vegetabledisposing Characteristic has heartLivingCreature disposedisposing Description Basic Living Creaturedisposing Characteristic is alive*///:~

        2、同时,当成员对象存在于其他一个或者多个对象共享的情况时,就不能单纯的只是调用dispose()方法去释放成员空间了,必须使用引用计数来跟踪另外还有几个对象在共享该成员对象了。方法是,使用一个变量来计数,本例中使用refcount计数

例程:

//: polymorphism/ReferenceCounting.java// Cleaning up shared member objects.import static net.mindview.util.Print.*;class Shared {  private int refcount = 0;  private static long counter = 0;  private final long id = counter++;  public Shared() {    print("Creating " + this);  }  public void addRef() { refcount++; }  protected void dispose() {    if(--refcount == 0)      print("Disposing " + this);  }  public String toString() { return "Shared " + id; }}class Composing {  private Shared shared;  private static long counter = 0;  private final long id = counter++;  public Composing(Shared shared) {    print("Creating " + this);    this.shared = shared;    this.shared.addRef();  }  protected void dispose() {    print("disposing " + this);    shared.dispose();  }  public String toString() { return "Composing " + id; }}public class ReferenceCounting {  public static void main(String[] args) {    Shared shared = new Shared();    Composing[] composing = { new Composing(shared),      new Composing(shared), new Composing(shared),      new Composing(shared), new Composing(shared) };    for(Composing c : composing)      c.dispose();  }} /* Output:Creating Shared 0Creating Composing 0Creating Composing 1Creating Composing 2Creating Composing 3Creating Composing 4disposing Composing 0disposing Composing 1disposing Composing 2disposing Composing 3disposing Composing 4Disposing Shared 0*///:~

        3、1和2两种结合在一起例程,本例中使用share计数:

package polymorphism;class Member {    public Member(String id) {        System.out.println("Member constructor " + id);    }    public void dispose(){    }}class Rodent2 {    private int share = 0;    Member m1 = new Member("m1"), m2 = new Member("m2");    public Rodent2() { System.out.println("Rodent constructor"); }    public void hop() {System.out.println("Rodent hopping"); }    public void scurry() { System.out.println("Rodent scurrying");}    public void reproduce() {System.out.println("Making more Rodents");}    public String toString() { return "Rodent"; }    public void add(){        share++;        System.out.println("Rodent2 was shared "+ share +" times");    }    public void dispose(){        if(--share ==0){            System.out.println("dispose Rodent2!");        }        System.out.println("Rodent2 now "+share+" times");        m2.dispose();//字段按照定义的相反顺序释放;        m1.dispose();    }    /*在虚拟机进行垃圾回收该内存时,检验是否满足这个条件,不满足的话,说明程序有隐藏的漏洞,可以帮助程序员发现这种具有不确定性(不定时发生的)的Bug;    判断条件为何为share>0?        继承(导出类中嵌入基类对象):由于继承关系中在导出类中释放空间时调用super.dispose()会产生share = -1的情况;        组成(通过引用在导出类中使用基类或者其他类的对象):当Rodent为成员变量时,调用dispose()会产生share = 0;    */    protected void finalize(){        if(share > 0){             System.out.println("Error: 还有引用,不能回收内存!");        }    }}class Mouse2 extends Rodent2 {    private static int counter = 0;    private final int id = counter++;    private Rodent2 rodent2 = new Rodent2();    Member m1 = new Member("m1"), m2 = new Member("m2");    public Mouse2() {System.out.println("Mouse constructor");}    public Mouse2(Rodent2 rodent2){        this.rodent2 = rodent2;        rodent2.add();        System.out.println("Mouse constructor");    }    @Override    public void dispose(){        System.out.print("Dispose Mouse2 "+ id +" share ");        rodent2.dispose();//字段按照定义的相反顺序释放;        m2.dispose();        m1.dispose();        super.dispose();//由于继承隐式的嵌入了基类的子对象在导出类中,所以也应该清除,并且应该注意的是:这个嵌入的子对象和本例中引用rodent2指向的对象不同,该子对象的share值为0,当调用super.dispose()后,share值变为-1;    }    @Override    public void hop() {System.out.println("Mouse hopping");}    @Override    public void scurry() {System.out.println("Mouse scurrying");}    @Override    public void reproduce() {System.out.println("Making more Mice");}    @Override    public String toString() { return "Mouse"; }}public class E12_RodentInitialization {    public static void main(String args[]) {        Rodent2 r2 = new Rodent2();        Mouse2[] mouse2s = {new Mouse2(r2),new Mouse2(r2),new Mouse2(r2),new Mouse2(r2),new Mouse2(r2)};        for(Mouse2 m2 :mouse2s){            m2.dispose();        }    }}/*OutputMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent2 was shared 1 timesMouse constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent2 was shared 2 timesMouse constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent2 was shared 3 timesMouse constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent2 was shared 4 timesMouse constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent constructorMember constructor m1Member constructor m2Rodent2 was shared 5 timesMouse constructorDispose Mouse2 0 share Rodent2 now 4 timesRodent2 now -1 timesDispose Mouse2 1 share Rodent2 now 3 timesRodent2 now -1 timesDispose Mouse2 2 share Rodent2 now 2 timesRodent2 now -1 timesDispose Mouse2 3 share Rodent2 now 1 timesRodent2 now -1 timesDispose Mouse2 4 share dispose Rodent2!Rodent2 now 0 timesRodent2 now -1 times */
阅读全文
0 0