java对象生命周期

java对象的生命周期包括几个阶段(并不是绝对的,有些对象并没有不可见这一过程):

  1. 创建阶段(Created) --构造创建初始化
  2. 应用阶段(In Use) --有变量引用
  3. 不可见阶段(invisible ---仅仅出了作用域
  4. 不可达阶段(Unreachable) --引用数为0 回收
  5. 收集阶段(Collected) --gc标记
  6. 终结阶段(Finalized) --调用finalize对对象进行销毁
  7. 对象空间重新分配阶段(De-allocated) --- 重新分配

1. 创建阶段

  • 为对象分配储存空间 (堆区)
  • 开始构造对象
  • 从超类到子类对static成员进行初始化(类初次加载的时候才有)
  • 超类成员变量按照顺序初始化,递归调用超类的构造方法
  • 子类成员变脸按照顺序初始化,子类构造方法调用

一旦对象被创建 并被分派给某些变量赋值或者置于容器中,这个对象的状态就切换到了应用阶段

    //构造方法
    public A(){
        System.out.println(" A init");
    }
    
复制代码

对象创建方式有多种:

  • 用new语句创建对象,这是最常见的创建对象的方法。

  • 通过工厂方法返回对象,如:String str = String.valueOf(23);

  • 运用反射手段,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。如:Object obj = Class.forName("java.lang.Object").newInstance();

  • 调用对象的clone()方法。

  • 通过I/O流(包括反序列化),如运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。

2. 应用阶段

对象至少被一个强引用持有着(包括被数组 和Java容器引用),正常使用且在作用域内。和创建阶段最主要的区别在于有没有引用指向它

 A a = new A(); // a指向 所以属于应用阶段
 List list = new ArrayList();
list.add(a); // 数组内会保存对象的引用  属于应用阶段 
 new A(); // 无强引用 创建即为不可达阶段
复制代码

3. 不可见阶段(invisible)

本质上来说就是已经过了作用域,但由于未对对象的引用进行手动指向null或者其他对象,所以会导致对象状态处于这种不可见状态,就是实质有变量引用,引用存在,但是使用区域超出作用域,如下面代码段所示,在输出i时已经过了i的作用域(这里在编译期就会报错),在这个时候其实已经不持有i变量引用,所以该对象属于不可见阶段。

 if(true) {
    int i = 1;    
 }
 System.out.println(i);
复制代码

4. 不可达阶段(Unreachable)

对象处于不可达阶段是指对象不被任何强引用持有,即引用计数为0.

A a = new A(); //新建一个对象 并有一个强引用 a指向它  引用计数为1 
a =null;  // a指向null,原有对象不再被强引用引用,所以对象变为不可达状态。(下次gc时会被回收)
//除此之外强引用还有 数组之类的容器
B b = new B(); //引用计数为1
List list = new ArrayList();
list.add(b); //引用计数 加1  计数器为2 
b = null;// 引用计数减1  这个时候引用计数为1 之前new出来的B的那个对象并不符合垃圾回收机制的规则,因为他被list持有。
list.remove(); //这个时候 list不再持有该对象, 引用计数减1 ,对象为不可达阶段,符合垃圾回收规则,将会在下一次gc被释放
复制代码

5. 收集阶段

对象标记为不可用时进入收集阶段,即垃圾回收器发现该对象为不可用。此时会调用finalize()。
注意:不要重载finalize方法,主要原因有亮点

  • 可能导致对象重新进入应用阶段,导致内存泄漏。在finalize方法中,如果对该对象新增其他强引用(引用指向,或者放入数组之类的容器),导致对象重新进入应用阶段,这种对象完全不利于后续的代码管理,无法对空间进行释放
  • 在分配该对象时,JVM需要在垃圾回收器上注册该对象,以便在回收时能够执行该重载方法;在该方法的执行时需要消耗CPU时间且在执行完该方法后才会重新执行回收操作,即至少需要垃圾回收器对该对象执行两次GC。

6.终结阶段

执行完 finalize方法,如果还是不可达状态 等待GC执行垃圾回收

7.对象空间再分配阶段(deallocated)

Deallocated状态是垃圾回收的最后一步,如果经过上面所有的阶段对象仍为unreachable,就可以进入deallocation阶段了。当然何时回收、再分配及相关算法取决于JVM虚拟机本身。

转载于:https://juejin.im/post/5c7dd329e51d4542141b6336

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值