Java是一门面向对象的语言。它能够遵循一种更接近于现实世界中解决常见问题的思考方式。为了更好地了解对象,我们应该了解对象的生命周期。一个对象在其生命周期中经历了多个阶段。
对象生命周期的各个阶段
普通的开发人员可能只重点关注了对象生命周期中的两到三个阶段,其中包括Created(创建阶段),In Use(使用阶段) 和 Finalized(终结阶段),这可能会导致应用程序的性能问题。如果开发人员希望他的代码高效且无bug,那么了解对象生命的各个阶段非常重要。另外,对这些阶段的正确了解也有助于减少内存泄漏。
Created(创建阶段)
创建对象意味着分配内存、调用构造函数并初始化其属性。创建对象后,即可使用该对象并将其保存在JVM的内存堆中。每个新手开发人员都知道如何创建一个对象。
public Dog getDog() {
Dog dog = new Dog(); // creation of Object Dog
return dog;
}
In Use(使用阶段)
任何被强引用的对象都被称为正在使用中。比如:在下面的代码中,Dog对象具有一个字符串引用dog。
Dog dog = new Dog();// Here dog is strong reference to Dog Object`
我们可以针对任意对象有多个强引用。在使用阶段,对象不允许被GC(垃圾回收)。“ Created”状态与“In Use”状态之间的区别在于,创建对象时,它可能正在使用也有可能未使用。您可以创建一个对象后,而无需引用即可将其忽略。在这种情况下,对象直接进入“Unreachable”状态。
....
//Creation of Dog Objects
Dog dog = new Dog();
Dog dog2 = new Dog();
dog = null;// Object refereed by dog directly goes to Unreachable state
}
Invisible (不可见阶段)
不可见对象可能会导致不必要的内存损耗,并且也可能影响性能。当引用和对象都超出作用域时,这些引用是不可访问的,即不可见引用。
public void execute() {
try {
Object obj = new Object();
} catch (Exception e) {
e.printStackTrace();
}
while(true){
…………….
………….
………….
}
}
在上面的示例中,当代码的执行进入无限while循环时,上面obj引用的Object 超出作用域范围,按道理应该被GC掉,但实际上obj引用还存活在当前方法栈帧中,Object对象也继续占用堆内存。如果此Object (由obj引用)的大小很大,并且在while循环之前有很多类似的内容,那么它可能会导致严重的内存损耗,并且很可能会导致OutOfMemoryException。
修复:要解决此问题,我们可以在使用引用后将引用显式设置为null。详见这篇:Java对象不再使用时赋值为null的作用和原理
Unreachable (不可达阶段)
当没有任何强引用指向该对象后,该对象将变得不可访问。该阶段对象可以被GC收集。
Dog dog = new Dog(); //line 1
dog = null; //line 2
在上面的代码中,第1行的对象在第2行变得不可访问。另外,GC也可以检测循环引用并收集它们。
Dog dog = new Dog(); //line 1
Owner owner = new Owner(); //line 2
dog.addOwner(owner); //line 3
owner.addPet(dog); //line 4
dog = null; //line 5
owner = null; //line 6
在上面的代码片段中,Dog和Owner对象都可以在第5行和第6行允许被GC收集。
Collected (收集阶段)
被GC识别为无法访问的对象后,该对象会进入收集阶段。如果对象具有finalize()方法,则将其标记为待终结,否则它将直接进入终结阶段。
如果对象具有finalize()方法,会在此处会发生额外的延迟。因此在编写finalize方法之前要慎重考虑下会不会对GC效率造成影响。
Finalized (终结阶段)
在调用对象的finalize()方法之后,如果该对象仍然不可访问,则对象进入终结阶段。finalize()方法仅被调用一次,不建议在这里处理各类资源的释放操作,因为会一直hold住资源直到GC调用finalize()方法。
Deallocated(释放阶段)
释放对象内存是垃圾收集的最后一步。如果一个对象在完成上述所有工作之后仍然无法访问,则允许释放该对象的内存。但是,何时以及如何进行释放取决于JVM。
原文地址:https://himanshugpt.wordpress.com/2010/03/17/life-cycle-of-java-object/