Java平台引用
一、创建类MyDate:
public class MyDate extends Date {
/** Creates a new instance of MyDate */
public MyDate() {
}
protected void finalize() throws Throwable {
super.finalize();
System.out.println("obj [Date: " + this.getTime() + "] is gc");
}
public String toString() {
return "Date: " + this.getTime();
}
}
在这个类中,对java.util.Date类进行了扩展,并重写了finalize()和toString()方法。
注:finalize()方法在JVM销毁对象时运行这个方法,finalize()方法不能保证一定被JVM执行。
二、创建测试类ReferenceTest
public class ReferenceTest {
/** Creates a new instance of ReferenceTest */
public ReferenceTest() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
}
public static void drainMemory() {
String[] array = new String[1024 * 10];
for(int i = 0; i < 1024 * 10; i++) {
for(int j = 'a'; j <= 'z'; j++) {
array[i] += (char)j;
}
}
}
}
在这个类中定义了一个静态方法drainMemory(),此方法旨在消耗大量的内存,促使JVM运行垃圾回收。
三、JVM什么时候运行垃圾回收
1、没有调用垃圾回收:
在main中添加如下代码:
public static void main(String[] args) {
MyDate date = new MyDate();
date = null;
}
运行程序:
<无任何输出>
解释:date虽然被置位null,但由于JVM没有执行垃圾回收操作,MyDate的finalize()方法没有被运行
2、显式调用垃圾回收:
在main中添加如下代码:
public static void main(String[] args) {
MyDate date = new MyDate();
date = null;
System.gc();
}
运行程序:
obj [Date: 1207972662525] is gc
解释:调用了System.gc(),使JVM运行垃圾回收,MyDate的finalize()方法被运行
3、隐式调用垃圾回收:
在main中添加如下代码:
public static void main(String[] args) {
MyDate date = new MyDate();
date = null;
drainMemory();
}
解释:虽然没有显式调用垃圾回收方法System.gc(),但是由于运行了耗费大量内存的方法,触发JVM进行垃圾回收。
总结:JVM的垃圾回收机制,在内存充足的情况下,除非你显式调用System.gc(),否则它不会进行垃圾回收;在内存不足的情况下,垃圾回收将自动运行
四、Java对引用的分类
级别 |
什么时候被垃圾回收 |
用途 |
生存时间 |
强 |
从来不会 |
对象的一般状态 |
JVM停止运行时终止 |
软 |
在内存不足时 |
对象简单?缓存 |
内存不足时终止 |
弱 |
在垃圾回收时 |
对象缓存 |
gc运行后终止 |
假象 |
Unknown |
Unknown |
Unknown |
1、强引用:
public static void main(String[] args) {
MyDate date = new MyDate();
System.gc();
}
解释:即使显式调用了垃圾回收,但是用于date是强引用,date没有被回收
2、软引用:
public static void main(String[] args) {
SoftReference ref = new SoftReference(new MyDate());
drainMemory(); // 让软引用工作
}
解释:在内存不足时,软引用被终止,等同于:
MyDate date = new MyDate();
//-------------------由JVM决定运行-----------------
If(JVM.内存不足()) {
date = null;
System.gc();
}
//-------------------------------------------------------------
3、弱引用:
public static void main(String[] args) {
WeakReference ref = new WeakReference(new MyDate());
System.gc(); // 让弱引用工作
}
解释:在JVM垃圾回收运行时,弱引用被终止,等同于:
MyDate date = new MyDate();
//------------------垃圾回收运行------------------
public void WeakSystem.gc() {
date = null;
System.gc();
}
4、假象引用:
public static void main(String[] args) {
ReferenceQueue queue = new ReferenceQueue();
PhantomReference ref = new PhantomReference(new MyDate(), queue);
System.gc(); // 让假象引用工作
}
解释:假象引用,在实例化后,就被终止了,等同于:
MyDate date = new MyDate();
date = null;
//-------终止点,在实例化后,不是在gc时,也不是在内存不足时--------