(1)GC Roots对象:
- 虚拟机栈中栈帧的本地变量表引用的对象
- 本地方法栈JNI(Native方法)引用的对象
- 方法区中的静态属性引用的对象
- 方法区中的常量引用的对象
(2)虚引用:无法通过虚引用来取得一个对象实例,唯一目的在于能在这个对象被收集器回收时收到一个系统通知。
(3)对象不可达时,进行第二次筛选标记。如果这个对象没有覆盖finalize方法或者虚拟机已经调用过finalize方法,则回收。如果覆盖了finalize方法,则将对象放在一个F-Queue队列中,由一个虚拟机建立的,低优先级的Finalizer线程去触发它,只要该方法中该对象重新与引用链上的任意一个对象建立关联,则这个对象逃逸,不被回收。
注意两点:对象可以在判定不可回收时可能完成自救;机会只有一次,因为一个对象的finalize方法最多只能被虚拟机调用一次。
(4)永久带垃圾回收的主要内容:废弃常量和无用的类。
废弃常量:没有任何对象引用这个常量
无用的类:该类的所有实例都被会回收,加载该类的ClassLoader已经被回收,该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法
(5)垃圾回收算法都是标记回收对象
标记清除:标记和清除效率低+空间碎片多
复制算法:不考虑内存碎片,移动堆顶指针,按顺序分配内存,运行高效 + 可用内存只有一半
标记整理:所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
(6)新生代:Eden+From Survior+To Survior (8:1:1),新生代每次可用内存约为90%,由老年代进行分配担保
(7)HotSpot算法实现:
- 枚举根节点:OopMap数据结构(GC扫描时得到信息) + Stop the World
- 安全点:指令中OopMap引用改变太多的问题 + 安全点Safepoint + 程序到达安全点才会GC + 如何让线程跑到最近安全点停下来 + 抢占式中断(不采用)+主动式中断
- 安全区域:解决程序不执行时问题。 安全区域Safe Region:一段代码中引用关系不会发生变化
(8)G1收集器的特点
- 并行与并发:缩短Stop fbe World 的时间
- 分代收集:
- 空间整合:从整体来看标记整理,从局部(狂歌Region)之间基于复制
- 可预测的停顿:
注意:使用G1收集器时,Java的内存布局不再是新生代与老年代,而是将整个Java堆划分成多个大小相等的独立区域(Region)。新生代和老年代不再是物理隔离,它们都是一部分Region(不需要连续)的集合。
G1避免不同Region的全堆扫描:G1中每个Region都有一个与之对应的Remembered Set
(10)对象优先在Eden分配,当Eden区不够时引发Minor GC
(11)长期存活的对象将进入老年代:对象年龄计数器(默认11),如果在survivor相同年龄所有对象大小的总和大于survivor空间的一半(单个survicor),年龄大于或等于该年龄的对象可以直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄。
(12)空间分配担保:发生Minor GC之前,先检查老年代最大可用连续空间是否大于新生代所有对象空间,若成立则Minor GC确保安全。
每次完成回收前是不知道有多少对象活下来,所以只好取之前每一次回收晋升到老年代对象容量的平均大小值作为经验值,与老年代的剩余空间进行比较,来决定是否需要Full GC。