强引用 :
A a = new A () ;
这就是强引用,只有a = null 或者a 不在指向堆中的 a 对象, a对象才会被jvm 回收
软引用 :
当内存容量不够时,随时可能被回收,当内存容量足够的时候不会被回收的一种引用.主要用来做缓存使用.
比如
public static void main(String[] args) {
// -Xmx20M jvm 分配20M运行内存
SoftReference<byte[]> demo = new SoftReference<>(new byte[1024 * 1024 * 10]);
System.out.println(demo.get());
System.gc();
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(demo.get());
// 在分配15M内存,这个时候, 软引用就会被回收
byte[] bb = new byte[1024 * 1024 * 15];
System.out.println(demo.get());
}
先分配一个10M的byte[],使用的是软引用,当后面再分配一个15M的内存的时候,软引用就会被回收
运行结果:
[B@515f550a
[B@515f550a
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.improve.soft.T_SoftReference.main(T_SoftReference.java:20)
理论结果应该是:
[B@515f550a
[B@515f550a
null
(这个没验证成功,会发生OOM,但是如果把内存调至25或者以上的时候,才会被回收.马士兵的视频是这么讲解和验证的,姑且先这么理解,如果有知道原因的,欢迎评论.)
这里面的byte[] 就是一个软引用
弱引用:
当垃圾回收时, 不管内存空间是否充足,都会被回收弱引用对象
public static void main(String[] args) {
WeakReference<Demo> demo = new WeakReference<>(new Demo());
System.out.println(demo.get()); // com.improve.Demo@515f550a
System.gc();
System.out.println(demo.get()); // null
}
TreadLocal中使用的就是弱引用
虚引用:
这个引用有跟没有一样,随时都可能被回收,不影响对象的生命周期,主要用来监控对象被垃圾回收活动,与软引用和弱引用的区别时,虚引用必须和引用队列(ReferenceQueue)一起使用.一般用于直接内存操作的对象(NIO, Netty zore copy 使用到)