1.gc主要发生在堆和方法区,其他区域随着线程的生灭,内存回收具有确定性。
2.判断对象是否已死(不可能再被任何途径使用的对象)
1)引用计数算法
给对象中添加一个引用计数器,每当有地方引用是就加一,当引用失效时,计数器减一,任何时刻计数器为0的对象就是不可能再被使用的。
缺点:很难解决对象之间的循环引用
2)跟搜索算法
通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。
在Java语言中,可以作为GCRoots的对象包括下面几种:
(1). 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。
(2). 方法区中的类静态属性引用的对象。
(3). 方法区中常量引用的对象。
(4). 本地方法栈中JNI(Native方法)引用的对象。
3.四种引用类型
4.回收方法区
方法区回收性价比不高
5垃圾收集算法
1)标记清除算法
首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象
后续算法都是基于这种思路的改进
缺点一标记和清除过程的效率都不高
二空间问题,标记清除后会产生大量不连续的内存空间,当需要分配较大对象是无法找到足够大的连续空间而提前触发垃圾回收
2)复制算法
将内存容量划分为大小相等的两块,每次只适用其中的一块,当一块用完了,就将还活着的对象复制到另一块上面,把已使用的内存空间一次清理掉。
商业虚拟机采用这种算法来回收新生代。内存空间划分比例不是一比一,而是分为Eden和两个survivor,比例为8.1
每次使用Eden和一个survivor,把活着的对象复制到另一个survivor,空间不够使用老年代进行担保
3)标记整理算法
标记过程与标记清除一样,后续让所有存活的对象想一端移动,然后清除掉端边界以外的内存。
4)分代收集算法
根据对象存活周期的不同将内存划分为几块,一般把java堆分为新生代和老年代,根据各个年代的特点采用最适当的收集算法
如新生代复制算法,老年代标记清除或者标记整理
6垃圾收集器