Weak references & Soft references

来源:互联网 发布:尚学堂大数据视频下载 编辑:程序博客网 时间:2024/06/05 02:21

看ThreadLocal源码的时候,产了一个疑问。
看来有问题,还是应该找英文原版啊, 中文博客文章害死人啊,也许是之前看博客看书没有读的仔细的原因。
一直以为弱引用就是在GC的时候就会立刻回收掉的,软引用是内存不够用的时候,GC才会去回收的。
但这里有一个前提:是没有任何强引用对象的时候才会去做的。
如下文:If there are no strong references to the widget.

Weak references

A weak reference, simply put, is a reference that isn’t strong enough to force an object to remain in memory. Weak references allow you to leverage the garbage collector’s ability to determine reachability for you, so you don’t have to do it yourself. You create a weak reference like this:

WeakReference weakWidget = new WeakReference(widget);
and then elsewhere in the code you can use weakWidget.get() to get the actual Widget object. Of course the weak reference isn’t strong enough to prevent garbage collection, so you may find (if there are no strong references to the widget) that weakWidget.get() suddenly starts returning null.

Soft references

A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. An object which is only weakly reachable (the strongest references to it are WeakReferences) will be discarded at the next garbage collection cycle, but an object which is softly reachable will generally stick around for a while.

SoftReferences aren’t required to behave any differently than WeakReferences, but in practice softly reachable objects are generally retained as long as memory is in plentiful supply. This makes them an excellent foundation for a cache, such as the image cache described above, since you can let the garbage collector worry about both how reachable the objects are (a strongly reachable object will never be removed from the cache) and how badly it needs the memory they are consuming.

And Peter Kessler added in a comment:

The Sun JRE does treat SoftReferences differently from WeakReferences. We attempt to hold on to object referenced by a SoftReference if there isn’t pressure on the available memory. One detail: the policy for the “-client” and “-server” JRE’s are different: the -client JRE tries to keep your footprint small by preferring to clear SoftReferences rather than expand the heap, whereas the -server JRE tries to keep your performance high by preferring to expand the heap (if possible) rather than clear SoftReferences. One size does not fit all.

## 一个小例子```javapackage arthur.dy.lee.test;import java.lang.ref.WeakReference;/** * Created by Administrator on 2017/7/6. */public class TestWeakReference {    public static void main(String[] args) {        Car car = new Car(22000, "silver");        WeakReference<Car> weakCar = new WeakReference<Car>(car);        int i = 0;        while (true) {            if (weakCar.get() != null) {                i++;                System.out.println("Object is alive for " + i + " loops - " + weakCar);            } else {                System.out.println("Object has been collected.");                break;            }        }        //car.doSomething();    }}class Car {    int    price;    String name;    public Car() {    }    public Car(int price, String name) {        this.price = price;        this.name = name;    }    public void doSomething(){            }}

这个例子网上抄过来的,如果没有下面的car.doSomething();
那么会打印

……..
Object is alive for 91107 loops - java.lang.ref.WeakReference@e9e54c2
Object is alive for 91108 loops - java.lang.ref.WeakReference@e9e54c2
Object is alive for 91109 loops - java.lang.ref.WeakReference@e9e54c2
Object is alive for 91110 loops - java.lang.ref.WeakReference@e9e54c2
Object is alive for 91111 loops - java.lang.ref.WeakReference@e9e54c2
Object has been collected.

如果加上car.doSomething();那么在while循环的时候,car一直是强引用,不会被GC,那么weakCar.get() 永远都不会为 null,即:System.out.println(“Object has been collected.”);永远都不会被执行。

参考:
https://stackoverflow.com/questions/299659/what-is-the-difference-between-a-soft-reference-and-a-weak-reference-in-java

原创粉丝点击