1. 可达性分析算法与 GC Roots
1.1 基本思路
- 可达性分析算法是以根对象集合(GC Roots)为起始点,按照从上至下的方式搜索被跟对象集合所连接的目标对象是否可达
- 使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用链(Reference Chain)
- 在可达性分析算法中,只有能够被根对象集合直接或间接连接的对象才是存活对象
1.2 哪些对象可以作为 GC Roots
- 虚拟机栈中引用的对象,比如:线程中被调用的方法中使用到的参数、局部变量等
- 本地方法栈内 JNI 引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象,比如字符串常量池里的引用
- 被 synchronized 持有的对象
- Java 虚拟机内部的引用:比如基本数据类型对应的 Class 对象,一些常驻异常(NullPointException),系统类加载器等
- 反映 jvm 内部情况的 JMXBean、JVMTI 中注册的回调、本地代码缓存等
2. 内存泄漏相关举例:
- 如果一个单例对象持有外部对象的引用,那么这个外部对象就不会被回收,可能导致内存泄漏的产生
- 资源类型文件或者网络连接如 Stream、datasource.getConnection(), socket 等 IO 连接必须手动 close, 否则是不能被回收的。
- 静态变量关联的对象生命周期和类的生命周期一样长,也可能导致内存泄漏
- ThreadLocal 可能导致内存泄漏