序
刚才在群里分享了一波收藏的资源 ,发现了一个问题 。太难了 ,资料一大堆 ,啥啥学不会 。
拉钩教育新上的一个课程 ,Android 工程师进阶 34 讲
背景
Java 语言比 C 语言开发者幸福的地方在于 ,我们不需要手动释放对象的内存 ,JVM 的垃圾回收器会为我们自动回收 。但是这种幸福是有代价的 ,一旦这种自动化机制出错 ,我们有不得不去深入了解 GC 的回收机制 ,甚至需要自己手动去调节这些自动化 。
Java 内存运行时区域的各个部分 ,其中程序计数器 、虚拟机栈 、本地方法栈 三个区域随线程而生 ,随线程而灭 ;栈中的栈帧随着方法的进入和退出而有条不紊的执行着出栈和入栈的操作。
什么是垃圾
就是内存中已经没有用的对象 。
既然是 " 垃圾回收 ",那就必须知道哪些对象是垃圾 。Java 虚拟机中使用一种叫作 " 可达性分析 " 的算法来决定对象是否可以被回收 。
可达性分析
JVM 把内存中所有对象之间的引用关系看作一张图 ,通过一组名为 " GC Roots " 的对象作为起点 ,从这些节点开始向下搜索 ,搜索所走过的路径称为引用链 ,最后通过判断对象是否可达来决定对象是否可以被回收 。
上图中 ,Object1 和 Object 2 跟 Object3 / Object 4 与 Root 之间都存在一条直接或者间接的引用链 。这也代表着他们跟 GC Root 之间是可达的 ,因为他们是不能被 GC 回收掉的 。而 Object 6 和 Object 7 虽然跟 Object 5 是有引用链 ,但是并不存在一条引用链链接他们与 GC Root ,所以当 GC 进行垃圾回收时 ,只要遍历到 Obkect 5 、Object 6、 Object 7的时候 就会将他们回收 。
GC Root 对象
在 Java 中 ,有以下几种对象可以作为 GC Root
1. Java 虚拟机栈 (局部变量表)中的引用的对象
2. 方法区中静态引用指向的对象
Class Test {
private static Object test;
}
3. 仍处于存活状态中的线程对象
4. Native 方法中的 JNI 引用的对象