GC roots
(暂时这么理解)由堆外指向堆内的引用.
- JAVA方法栈帧中的局部变量.
- 已经加载类的静态变量
- JNI handles
- 已启动且未停止的JAVA线程
引用计数法
无法回收循环引用的
可达性分析
从GC roots出发,所有可达的对象加入存活合集,那么没有探测到的对象便是死亡,可以回收的.
在垃圾回收过程,为防止其他线程干扰,会停掉非垃圾回收的所有线程.
Stop the world.通过安全点实现.
垃圾回收的三种方式
- 清除
将死亡对象占据的内存记录在空闲列表中,当需要内存时,从列表查找.
缺点
(1) 会造成内存碎片,可能出现总内存足够,但无法分配的极端情况.
(2) 分配效率低,需要查表. - 压缩
把存活对象聚集到内存区域的起始位置.
缺点
额外的算法开销 - 复制
将内存区域分为两份,用from和to指针维护,当发生垃圾回收时,将from的存活对象
复制到to里,然后交换from和to的内容.
缺点
堆空间利用率低.
JAVA虚拟机的堆划分
堆划分为两个部分,分别是新生代,和老年代.
新生代又包含Eden 和 两个 Survivor区(from和to).
虚拟机采用动态分配策略,会根据Eden和survivor的使用情况,动态改变两者的内存比例.