Java(对象的生命周期)
1.对象的整个生命周期大致可以分为7个阶段:创建阶段(Creation)、应用阶段(Using)、不可视阶段(Invisible)、不可到达阶段(Unreachable)、可收集阶段(Collected)、终结阶段(Finalized)与释放阶段(Free)。
2.创建阶段:一个Java类(除Object类外)至少有一个父类(Object),这个规则既是强制的,也是隐式的。你可能已经注意到在创建一个Java类的时候,并没有显式地声明扩展(extends)一个Object父类。创建对象时应该遵循的规则:避免在循环体中创建对象,即使该对象占用内存空间不大;不要对一个对象进行多次初始化,这同样会带来较大的内存开销,降低系统性能。
3.应用阶段
3.1.强引用(Strong Reference)是指JVM内存管理器从根引用集合(Root Set)出发遍寻堆中所有到达对象的路径。当到达某对象的任意路径都不含有引用对象时,对这个对象的引用就被称为强引用。
3.2.软引用(Soft Reference)的主要特点是具有较强的引用功能。只有当内存不够的时候,才回收这类内存,因此在内存足够的时候,它们通常不被回收。
3.3.弱引用 GC在进行回收时,需要通过算法检查是否回收Soft引用对象,而对于Weak引用对象, GC总是进行回收。因此Weak引用对象会更容易、更快被GC回收。
3.4.虚引用(Phantom Reference)的用途较少,主要用于辅助finalize函数的使用。Phantom对象指一些执行完了finalize函数,并且为不可达对象,但是还没有被GC回收的对象。
4.不可视阶段
如果一个对象已使用完,而且在其可视区域不再使用,此时应该主动将其设置为空(null)。这样做的意义是,可以帮助JVM及时地发现这个垃圾对象,并且可以及时地回收该对象所占用的系统资源。
5.不可到达阶段
在虚拟机所管理的对象引用根集合中再也找不到直接或间接的强引用,这些对象通常是指所有线程栈中的临时变量,所有已装载的类的静态变量或者对本地代码接口(JNI)的引用。这些对象都是要被垃圾回收器回收的预备对象,但此时该对象并不能被垃圾回收器直接回收。其实所有垃圾回收算法所面临的问题是相同的——找出由分配器分配的,但是用户程序不可到达的内存块。
6.可收集阶段、终结阶段与释放阶段
垃圾回收器发现该对象已经不可到达。
finalize方法已经被执行。
对象空间已被重用。
当对象处于上面的三种情况时,该对象就处于可收集阶段、终结阶段与释放阶段了。虚拟机就可以直接将该对象回收了。
也可以分为对象的创建,对象的使用,对象的回收三部分。
一.对象的创建
1.步骤:(1)声明对象变量;(2)对象的实例化
2.创建与初始化:(1)分配内存空间;(2)显式初始化;(3)执行构造方法。
二.对象的使用
用过圆点运算符,可以访问对象的状态和方法
objectReference.variableName;
objectReference.methodName(argumentList);
三.对象的清除
1.垃圾收集器:堆中几乎存放着Java世界中所有的对象实例,垃圾收集器在对堆进行回收前首先要确定哪些对象还活着,哪些对象已经死去。Java中垃圾回收机制:自适用垃圾回收机制。停止-复制:先停止程序的运行,然后将所有活着的对象复制到另一个堆,没有被复制的全部是垃圾。缺点需要额外的操作空间(两个堆)。程序稳定后,只会产生少量的垃圾,甚至没有垃圾,直接复制的话,这很浪费。标记--清扫:从堆栈和静态存储区出发,遍历所有引用,进而找到所有存活的对象。每当找到一个活的对象,就会给对象设一个标记,这个过程中不会回收任何对象。只有标记工作完成,才会开始清理动作。剩下的对空间是不连续的,如果垃圾回收器希望得到连续的空间,就得重新整理剩下的对象。Java虚拟机会监视资源,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到“标记-清扫”;同样,如果堆空间出现很多碎片就会切换回“停止-复制”方式。这就是“自适用”技术。
2.对象的最终化处理:为了释放一些特殊的内存(如:natvie方法),java允许在类中定义一个名为finalize()的方法。原理:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并且在下一次垃圾回收动作是,才会真正回收对象占用的内存。因此:我们就可以在finalize()中,调用free()等释放内存的方法。如果对象中含有其他对象(普通java对象),finalize应该明确释放那么对象吗?不,对于java中的对象,不管是如何创建的,垃圾回收器都会负责释放对象占据的内存,最好要在finalize中对一般java对象做释放操作。