## 哪些区域需要垃圾收集
在[熟悉Java内存区域](001%E7%86%9F%E6%82%89Java%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F.md)文中,知道了JVM运行时数据区有堆、方法区、虚拟机栈、本地方法栈和程序计数器5个部分,后3个部分都是线程私有的,其中的数据会跟随线程死亡自动回收,所以不需要垃圾收集。而堆和方法区是线程共享的,故垃圾收集主要关注这2个部分。
学习了[垃圾判定算法与4大引用](004%E5%9E%83%E5%9C%BE%E5%88%A4%E5%AE%9A%E7%AE%97%E6%B3%95%E4%B8%8E4%E5%A4%A7%E5%BC%95%E7%94%A8.md)后,我们知道了如何判断对象是垃圾了。
接下来,我们就开始回收堆和方法区中的无效数据。
## 回收堆
对于可达性分析中不可达的对象,也并不是没有存活的可能。
### 判定 finalize() 是否有必要执行
JVM 会判断此对象是否有必要执行 `finalize() `方法,如果对象没有覆盖 `finalize() `方法,或者 `finalize()` 方法已经被虚拟机调用过,那么视为“没有必要执行”。那么对象基本上就真的被回收了。
如果对象被判定为有必要执行 `finalize()` 方法,那么对象会被放入一个 `F-Queue` 队列中,虚拟机会以较低的优先级执行这些 `finalize()`方法,但不会确保所有的 `finalize()` 方法都会执行结束。如果 `finalize()` 方法出现耗时操作,虚拟机就直接停止指向该方法,将对象清除。
### 对象重生或死亡
如果在执行 `finalize()` 方法时,将 this 赋给了某一个引用,那么该对象就重生了。如果没有,那么就会被垃圾收集器清除。
**任何一个对象的 finalize() 方法只会被系统自动调用一次,如果对象面临下一次回收,它的 finalize() 方法不会被再次执行,想继续在 finalize() 中自救就失效了。**
## 回收方法区
方法区存放生命周期较长的已加载的类信息、常量、静态变量和即时编译器编译后的代码4个部分,主要回收:
* 无用的类
* 废弃常量
### 判定无用的类
判定一个类是无用的,条件比较苛刻:
* 该类的所有对象都已被清除。
* 加载该类的`ClassLoader`被回收。
* 该类的`java.lang.Class`对象没有被任何地方引用,无法在任何地方通过反射访问该类的方法。
满足上面3个条件的类,虚拟机会进行回收。(通过`-Xnoclassgc`参数控制)
一个类被虚拟机加载进方法区,那么在堆中就会有一个代表该类的对象:`java.lang.Class`。这个对象在类被加载进方法区时创建,在方法区该类被卸载时清除。
在大量使用反射、动态代理、CGLib等字节码框架、动态生成JSP以及OSGI这类频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以保证方法区不会溢出。
### 判定废弃常量
条件:只要常量池中的常量不被任何变量或对象引用,那么这些常量就会被清除掉。
比如,一个字符串 "abc" 进入了常量池,但是当前系统没有任何一个 String 对象引用常量池中的 "abc" 常量,也没有其它地方引用这个字面量,必要的话,"abc"常量会被清理出常量池。
## 参考资料
* 周志明 * 《深入理解Java虚拟机》
- 面试突击
- Java虚拟机
- 认识字节码
- 000Java发展历史
- 000Macos10.15.7上编译OpenJDK8u
- 001熟悉Java内存区域
- 002熟悉HotSpot中的对象
- 003Java如何计算对象大小
- 004垃圾判定算法与4大引用
- 005回收堆和方法区中对象
- 006垃圾收集算法
- 007HotSpot虚拟机垃圾算法实现篇1
- 007HotSpot虚拟机垃圾算法实现篇2
- 007HotSpot虚拟机垃圾算法实现篇3
- 008垃圾收集器
- 009内存分配与回收策略
- 010Java虚拟机相关工具
- 011调优案例分析
- 012一次IDEA的启动速度调优
- 013类文件Class的结构
- 014熟悉字节码指令
- 015类加载机制(过程)
- 016类加载器
- IDEA的JVM参数
- Java基础
- Java自动装箱与拆箱
- Java基础数据类型
- Java方法的参数传递
- Java并发
- 001走入并行的世界
- 002并行程序基础
- 003熟悉Java内存模型JMM
- 004Java并发之volatile关键字
- 005线程池入门到精通
- 006Java多线程间的同步控制方法
- 007Java维基准测试框架JMH
- 008Java并发容器
- 009Java的线程实现
- 010Java关键字synchronized
- 011一些并行模式的熟悉
- 单例模式和不变模式
- 生产者消费者模式
- Future模式
- 012一些并行算法的熟悉
- 面试总结
- 长亮一面