<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
关于 Java 的对象的创建和回收机制的小结
1 Java 中对象的创建方式
平时我们写的一条创建对象的语句,如: Object o = new Object(); ,就是创建了一个 Object 的对象,并且有 o 来应用这个对象,必须强调的一点是—— Java 是没有指针这个概念的,所以这里说的是引用。
当执行过这一条语句之后,在内存中就会出现两个位置,用于保存 o 和 o 所引用的对象,这两个地方分别是一个栈和一个堆,在栈里放的是引用 o ,在堆里放的是 o 所引用的对象,那么 o 是怎么引用到那个新创建的对象的呢?这里需要说明一点,其实本质上在栈里的引用变量存放的都是一串代表 0 或 1 的位,这一些位组合起来便是在堆里的对象的地址,这有点像是 C 语言里的指针。
如果又有一个 Object o2 = o; 那么 o2 这个变量也会保存到栈里面,并且 o2 在栈里的值和 o 是相同的,也就是说 o2 和 o 引用的是同一个对象。但是如果有: Integer i1 = new Integer ( 1 ) ; 和 Integer i2 = new Integer(1); 这两条语句,那么将会在堆里生成两个不同的对象,并且分别由 i1 和 i2 引用,也就是说这时候 i1 和 i2 内的位组成的数值时不相等的。
2 Java 中对象的销毁机制
Java 对象的销毁机制又称作 GC 机制,就是垃圾回收的意思,其实在 Java 中的 api 中有提供 System.gc() ;这个方法进行垃圾回收,但是必须说明的是 System.gc() ;这个方法只是“建议” JVM 进行垃圾回收,但是事实上 JVM 在调用这个代码的时候是否进行垃圾回收,那是不确定的!一般而言, JVM 都会在它认为必要的时候才自动进行 GC 操作,所以个人认为在代码中人为的调用 gc() 意义不大。
怎样的对象是 JVM 认为可以回收的呢?其实就是没有用的对象, JVM 就会认为可以回收了。而 JVM 对没用的对象的定义是——没有有效引用的对象!比较好理解的是没有引用的对象,就是说这个对象没有至少一个引用变量引用了,如上面所创建的 o 引用的 Object 对象,现在我们将 o = null; 这个时候这个 Object 依然不能被认为是可以 GC 的,因为还有一个 o2 在引用它,所以我们再将 o2 = null; 这个时候, JVM 可以认为这个 Object 对象是可以 GC 的了,当然前提是假设没有其它变量再引用它了,当然也得看 JVM 什么时候进行 GC ,所以在这时我们至少可以确认这个 Object 对象不能被我们调用了,它是否还在内存,这就是 JVM 做的工作了。
现在我来介绍一下什么叫做有效的引用,请看如下 代码:
当 23 行代码执行完后, smooch 和 booch 是否可以被 GC 呢?答案是可以的!这是因为虽然 booch 和 smooch 互相引用,但是我们已经无法再从外部调用这两个对象了,这就是俗称的孤岛参照,也就是无效的引用!所以 JVM 会在这个时候发现他们,并认定他们是可以被回收的对象。