对于这个做开发没有用到过,查网上可以用来做“高内存压力的缓存”,不懂,做个标识以后再看一下.
之前一直没有接触过弱引用这个概念,今天看到以后觉得挺新鲜,就查了查资料总结一下,希望对大家有所帮助。
要理解弱引用,首先要先了解一下强引用(Strong Reference), 其实我之前也并不了解强引用,虽然天天都在用。举例来说:
- String abc = new String ( "abcdf" );
弱引用就是不保证不被垃圾回收器回收的对象,它拥有比较短暂的生命周期,在垃圾回收器扫描它所管辖的内存区域过程中,一旦发现了只具有弱引用的对象,就会回收它的内存,不过一般情况下,垃圾回收器的线程优先级很低,也就不会很快发现那些只有弱引用的对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用的对象被垃圾回收的话,Java虚拟机就会把这个弱引用加入相关的引用队列中。
一下就是创建弱引用对象的例子。
- String abc = new String( "abcde" );
- WeakReference<String> wf= new WeakReference<String>(str, rq);
String abc1 = wf.get()//如果abcde这个对象没有被垃圾回收器回收,那么abc1就指向"abcde"对象
==========================================
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 时,也不是在内存不足时 --------