synchronized 会使被锁对象成为 gc roots,确保其在锁持有期间不可回收;锁释放后即退出 gc roots,若无其他引用则可被回收。

synchronized 会影响 GC 对对象存活的判定,因为它会让被锁住的对象成为 GC Roots 的一部分。
被 synchronized 持有的对象是 GC Roots
Java 垃圾回收器通过可达性分析判断对象是否存活,起点是一组被称为 GC Roots 的对象。只要一个对象能通过引用链连接到任意 GC Root,它就被视为“存活”,不会被回收。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
其中明确包括:所有被 synchronized 关键字持有的对象(即作为 monitor 锁的对象)。这意味着: - 当前线程执行 synchronized(obj) { ... } 时,obj 被加锁; - 此时 obj 就进入了 GC Roots 集合; - 即使代码中已无其他强引用指向 obj,只要锁未释放(比如还在同步块内),GC 就不能回收它。
实际影响场景
- 同步块内临时创建但未显式引用的对象,若被用作锁,会因“被锁持有”而暂存不被回收;
- 锁对象本身生命周期可能被意外延长——例如在长耗时同步操作中,即使业务逻辑早已不再需要该对象,只要锁没退出,它就一直算“存活”;
- 若锁对象是大型对象(如大数组、缓存容器),可能延迟其进入老年代或触发提前晋升,间接影响 Minor GC 和 Full GC 行为。
注意:锁释放后立即解除 GC Root 身份
synchronized 是 JVM 层的监视器机制,锁的持有与释放由字节码指令 monitorenter / monitorexit 控制。一旦线程退出同步块(或发生异常并完成解锁),该对象就不再属于 GC Roots。下一次 GC 标记阶段,若它已无其他引用链可达,就会被正常标记为可回收。
和引用类型无关,只与锁状态有关
这种影响不依赖于对象的引用类型(强/软/弱/虚),也不受 finalize() 或 ReferenceQueue 干预。它是 JVM 底层对锁对象的硬性保障:只要锁着,就必须保活。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










