Java中的对象实例存储在堆里,引用就是为了找到对象实例的指针。GC会根据对象实例不同的引用来进行垃圾回收。
- 强引用
是默认的,基本的引用,最为常见,比如 Object obj = new Object(); // obj是强引用
永远不会被回收
下面三种引用方式是后来引入的,允许开发者更灵活地控制对象的生命周期。具体实现在java.lang.ref中。其中 Reference.java是抽象基类和jvm紧密相连。
public class WeakReference<T> extends Reference<T> {
/**
* Creates a new weak reference that refers to the given object. The new
* reference is not registered with any queue.
*
* @param referent object the new weak reference will refer to
*/
public WeakReference(T referent) {
super(referent);//传入的对象指针继续向上传递,直到Reference中的 private T referent;受到jvm的管理。
}
public WeakReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}
}
- 软引用
当内存不足时会被回收 - 弱引用
无论内存是否充足,GC 都会回收弱引用对象 - 虚引用
虚引用是最弱的引用类型。虚引用对象无法通过get()
方法获取,主要用于对象回收时的跟踪
分析的代码均为JDK 8 ,后来的版本又引入了新的类型。
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);//将k(指向ThreadLocal的对象的指针)向上传递,标注为弱引用类型。
value = v;
}
}
- 知道threadlocalmap中的Entry中的key是对ThreadLocal的弱引用,当外部没有强引用时,ThreadLocal就会被垃圾回收,k 值变为 null。但value是强引用,的生命周期很长随Thread,Thread -> threadLocals -> threadLocalMap -> Entry -> value -> object,大量未使用的value就会造成内存泄露.
- 可以手动 remove,ThreadLocal中的 set ,get 方法也可以自动的帮助我们清理一部分value的值。
所以用完的对象要即使清理。
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现