一、JAVA对象创建

java对象的创建分为两部分:初始化对象、实例化对象

1、什么是初始化对象

当我们new一个对象的时候,虚拟机会执行一条new指令,根据这个指令的参数,去常量池中检测是否存在一个类的符号引用,并检查这个符号代表的类是否被加载、解析及初始化过。如果没有,那必须执行相应的类加载过程对类进行初始化。
在类加载完成后,才会实例化对象。(类的初始化是由类的构造器完成的)

2、什么是实例化对象

实例化对象就是虚拟机在java堆中为对象分配内存空间。对象所需的内存大小在类加载完成后就确定了,与是否初始化完成无关。实例化的时候,java虚拟机会为对象分配内存来存放其从父类继承过来的实例变量。在这些实例变量分配内存的同时,这些实例变量会先被赋予默认值。在内存分配完成后,虚拟机才会为新创建的对象赋予我们程序员给定的值。

3、类的初始化

举一个简单的例子

java 释放File对象 java释放创建的对象_java 释放File对象


输出结果

java 释放File对象 java释放创建的对象_JAVA_02


这里大家都应该知道普通变量是没办法在静态代码块中输出,因为加载静态代码块的时候普通变量还没有被加载。再举一个有父类情况下类的初始化

java 释放File对象 java释放创建的对象_JAVA_03


java 释放File对象 java释放创建的对象_JAVA_04


输出结果

java 释放File对象 java释放创建的对象_虚引用_05

二、JAVA对象回收

1、对象已死吗

在堆中几乎存放着JAVA世界中所有的对象实例,垃圾收集器在对堆回收之前,第一件要确定的事就是那些对象还“存活”,那些对象已经“死亡”(即不再被任何途径所使用)。
判断对象是否存活的两种方法:引用计数算法、可达性分析算法

(1)引用计数算法

引用计数算法就是给对象添加一个计数器,每当有一个地方引用他的时候他都会加1;当引用失效时计数器值减1;当计数器的值为0时,就代表对象已经“死亡”;
目前主流的JAVA虚拟机没有选取引用技术算法管理内存,其中最主要的原因是没有办法解决对象之间相互引用的情况。

(2)可达性分析算法

可达性分析算法是目前主流JAVA虚拟机所使用管理内存的算法,其思路是通过一系列被称为“GC ROOTS”的对象为起点,从这个节点向下搜索,搜索所有走过的路径称为“引用链”,当一个对象到GC ROOTS 没有任何引用链相连接时,则证明此对象是不可用的(图示,就是当从GC ROOTS到这个对象不可达)。如图所示,object5、object6、object7虽然互相连接,但是它们到GC ROOTS是不可达的,所以它们将被判定为可回收对象。

java 释放File对象 java释放创建的对象_JAVA_06


在JAVA语言中,可作为GC ROOTS的对象包括以下几种

1、虚拟机栈中引用的对象(栈帧中的本地变量表)

2、方法区中类静态属性引用的对象

3、方法区常量引用的对象

4、本地方法栈中(Native方法)引用的对象

三、引用

无论是通过引用计数算法还是可达性分析算法,判断对象是否存活都与引用有关。在jdk1.2以前的版本,java中的引用定义很传统,如果reference类型的数据中存储的数值代表另外一块内存的起始地址,就称这块内存代表着引用。
但是这种方式太过狭义,只能将一对象的状态分为引用和未被引用两种,对于一些食之无味,弃之可惜的对象来说就显得无能为力了。
所以在jdk1.2之后,java对引用对象进行了扩充,将引用分为强引用(Strong reference)、软引用(Soft reference)、弱引用(weak reference)、虚引用(phantom reference)4种,这4种引用的强弱依次递减。

强引用(Strong reference)

强引用就是在程序代码中普遍存在的,类似“Object obj = new Object()”这类的引用,只要强引用还存在,垃圾回收器永远不会回收被引用对象。

软引用(Soft reference)

软引用一般用来描述,还有用但非必须的对象。在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有满足内存才会抛出内存溢出异常。在jdk1.2以后提供SoftReference类来实现软引用。

弱引用(weak reference)

弱引用也是用来描述非必须引用对象的,它比软引用的强度更弱一些。被弱引用关联的对象只能生存到下次垃圾回收之前,当垃圾收集器工作时,无论当前内存是否足够,都回收掉只被弱引用的对象。用WeakReference类来实现弱引用。

虚引用(phantom reference)

虚引用是最弱的一中引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取对象实例,为一个对象设置虚引用的唯一目的就是能在对象被回收的时候收到一条系统通知。用PhantomReference类来实现虚引用。
如上所述有不正确的地方,还望指正。