Java中的强引用、软引用、弱引用、虚引用

Java中一共有4种引用类型,分别为:

  1. 强引用
  2. 软引用
  3. 弱引用
  4. 虚引用

1. 强引用

M m = new M();
m = null;
System.gc(); 

这个m指向M()内存对象的引用就是一个强引用。
image

2. 软引用

SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 1024 * 10]);
System.out.println(m.get());
System.gc();
System.out.println(m.get());
bye[] b = new byte[1024 * 1024 * 15]; // 10M + 15M > 20M
System.out.println(m.get()); // null 软引用被回收了

image

软引用主要用在缓存中,新来的Object如果分配不下了,就会被回收。

3. 弱引用

WeakReference<M> m = new WeakReference<>(new M());
System.out.println(m.get()); // com.xxx.M@ssdad
System.gc();
System.out.println(m.get()); // null

image
弱引用, 发生垃圾回收的时候,被引用对象被回收

常见的应用于ThreadLocal:线程本地对象

ThreadLocal<M> tl = new ThreadLocal<>();
t1.set(new M());
t1.remove();

image

ThreadLocal中的set方法

public void set(T value) {
	Thread t = Thread.currentThread();
	ThreadLocalMap map = getMap(t);
	if (map != null) {
		map.set(this, value);
	} else {
		createMap(t,value);
	}
}

ThreadLocalMap中的set方法

public void set(TheadLocal<?> key, Object value) {
	// 这里的Entry继承于WeakReference 
	// static class Entry extends WeakRefrence<ThreadLocal<?>>();
	tab[i] = new Entry(key, value);
}

为什么entry是一个Entry extends WeakReference ?

  • 为了防止内存泄漏,如果tl = null ,那么当出现垃圾回收的时候,ThreadLocal能够被gc()回收掉。
    但是这样也是不够的,因为threadLocal中的entry还存在呀,如果一旦不使用这个threadLocal时,也需要调用
    tl.remove()去删除threadLocal中的entry。

补充: ThreadLocal也被应用于Spring中的@Transactional中,对于不同的方法来说,如果去保证他们拿到的connection是同一个connection,这里就是使用的ThreadLocal来保存这个connection。

4. 虚引用

ReferenceQueue<M> QUEUE = new RefenceQueue<>();
PhantomReference<M> phontomRefence = new PhantomReference<>(new M(), QUEUE);
phontomRefence.get(); // null 拿不到,和没有一样的

image

主要用于来管理堆外内存。
堆外内存如何被回收的?
某个信息被OS加入到这个队列里面,也就是说如果没有指向DirectByteBuffer的对象了,要同时将对外内存也回收掉。
即如果这个队列中存在了element,就代表有堆外内存需要被回收

Reference<? extend M> poll = QUEUE.poll();
if (poll != null) 代表不空,那么就回收

参考: https://blog.csdn.net/Hellowenpan/article/details/121264731

posted @   CrazyShanShan  阅读(224)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示