Java的WeakReference相关

  • 什么WeakReference?

Car car = new Car(22000);

弱引用: WeakReference<Car> weakCar = new WeakReference<Car>(car);

可以这样理解:weakCar类似于car的指针,可以通过weakCar.get()得到car对象,当car对象需要被回收的时候(比如被置为null),weakCar也会在一段时间内被系统回收。

一段测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//设置-Xmx1M,即JVM堆内存最大为1M的环境运行
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
public class Car {
private double price;
public Car(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public static void main(String[] args) {
Car car = new Car(22000);
WeakReference<Car> weakCar = new WeakReference<Car>(car);
int i = 0;
// 运行62332次weakCar被回收
while (true) {
// 如果加了这句引用强引用的car对象后weakCar就不会被回收,无限循环
// System.out.println("here is the strong reference 'car' " + car);
if (weakCar.get() != null) {
// 使用weakCar.get()取得强引用,即使上一句if判断了也可能在这句之前被回收返回null,因此加try语句
try {
System.out.println("Object is alive for " + i + " loops - "
+ weakCar.get().getPrice());
i++;
} catch (NullPointerException e) {
e.printStackTrace();
}
} else {
System.out.println("Object has been collected.");
break;
}
// 如果把car置为null,那么weakCar16次循环后被回收
//car = null;
}
System.out.println("out of weakCar while");
// 这里用HashMap,就会产生堆内存溢出的异常,而WeakHashMap不会
WeakHashMap weakMap = new WeakHashMap<Integer, byte[]>();
for (int index = 0; index < 10000; index++) {
Integer ii = new Integer(index);
weakMap.put(ii, new byte[index]);
System.out.println("WeakHashMap for running" + ii + "times");
}
}
}

总结:一旦系统内存回收,无论内存是否紧张,弱引用指向的对象都会被回收
soft reference和weak reference一样, 但被GC回收的时候需要多一个条件: 当系统内存不足时(Heap 内存是否临近阈值),因此soft reference适合做cache object

WeakHashMap:hashmap的weak版,不保证map中的键值对的存在时间,在没有调用任何赋值方法(set相关)的情况下,在一段时间后 size 方法也可能返回较小的值,对于 isEmpty 方法,返回 false,然后返回 true,对于给定的键,containsKey 方法返回 true 然后返回 false,对于给定的键,get 方法返回一个值,但接着返回 null,对于以前出现在映射中的键,put 方法返回 null,而 remove 方法返回 false,对于键集、值集、项集进行的检查,生成的元素数量越来越少。总的来说就是map中的键值对会在GC回收的时候被回收

在WeakHashMap的get(),put()函数中的getTable()方法会调用expungeStateEntries方法,以清理持有弱引用的key的表项

JVM虚拟机运行配置

-Xms128m JVM初始分配的堆内存

-Xmx512m JVM最大允许分配的堆内存,按需分配

-XX:PermSize=64M JVM初始分配的非堆内存

-XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配