Java:如何查找特定类实例的所有引用?排查对象未释放问题
嘿,这个问题我太熟了——碰到对象本该被GC回收却赖在内存里的情况,揪出隐藏的引用绝对是关键。下面给你说说用Eclipse和其他工具的具体操作方法:
用Eclipse相关工具查找引用
1. 调试时直接查看引用(Eclipse Debug透视图)
当你的应用处于调试暂停状态时:
- 在
Variables视图里定位到目标类的实例 - 右键点击这个实例,选择
Inspect - 在弹出的检查窗口中,展开
References节点,就能看到所有持有该对象的引用——包括类的字段、当前栈帧里的局部变量,甚至是线程持有的引用 - 要是想追踪完整的引用链(也就是哪些对象间接让它没法被回收),可以查看
Retained References节点,它会展示整个引用树的根源
2. Eclipse Memory Analyzer (MAT)插件(深度分析)
这是处理内存问题的利器,适合排查复杂的引用情况:
- 先导出应用的堆转储文件:
- 在Eclipse里可以通过
Run > Profile As > Java Application,启动Profiler后触发堆转储 - 或者用JDK自带的命令行工具
jmap生成:jmap -dump:format=b,file=heapdump.hprof <你的应用PID>
- 在Eclipse里可以通过
- 用MAT打开这个
.hprof文件 - 点击左侧的
Histogram,在搜索框输入目标类的全名 - 找到对应类的条目后,右键选择
List Objects > With Incoming References,就能看到所有指向该类实例的引用,展开每个引用还能追溯到最开始持有它的对象(比如静态集合、线程对象等)
其他实用工具
VisualVM(JDK自带)
不需要额外安装,JDK默认自带:
- 打开VisualVM,连接到运行中的Java应用
- 切换到
Profiler标签,点击Memory下的Take Snapshot生成内存快照 - 在快照的
Classes列表里找到目标类,右键选择Show Instances - 选中某个实例后,查看右侧的
References面板,就能看到所有持有该实例的引用
IntelliJ IDEA内存调试(如果用IDEA开发)
如果你的开发环境是IDEA,操作同样直观:
- 调试时在
Variables视图选中目标对象,右键选择Show References - 或者用IDEA的Memory Profiler导出堆快照,之后在快照里搜索目标类,查看实例的引用链
小提示
排查时重点关注这些容易“留对象”的地方:
- 静态字段或静态集合类的引用
- 线程局部变量(
ThreadLocal)未清理 - 集合类(比如HashMap、ArrayList)中未移除的条目
- 未关闭的资源(比如流、连接)间接持有对象引用
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

