垃圾回收与算法
如何确定垃圾
- 引用计数法:在java中引用与对象是有关联的,如果要操作对象,必修用引用进行,如果引用计数为0,则这个对象可被回收
- 可达性分析:如果在GC roots和一个对象之间没有可达路径,则该对象不可达,可以被回收
标记清除算法(Mart-Sweep)
- 最基础的垃圾回收算法
- 分为标注和清除两个阶段
- 从图中可以看出内存碎片化严重,后续可能发生大对象找不到可以适用的空间
复制算法(copying)
- 为了解决Mark-Sweep算法内存碎片化的缺陷提出的算法
- 将内存分为两块,每次只是用一块,当这一块满了后,复制到另一快上去,再把已使用的清除掉
- 内存被压缩到原来的一半
标记整理算法
- 解决标记清除算法和复制算法的缺陷而提出的,标记后不是清理对象而是将存活对象移至内存的一端,然后清除端边界外的对象。
分代收集算法
- 是现在大部分JVM的所采用的算法,根据对象存活的不同生命周期将内存划分为不同的域,一般将GC堆分为新生代和老年代
新生代与复制算法
老生代与标记复制算法
- JAVA 虚拟机提到过的处于方法区的永生代(Permanet Generation),它用来存储 class 类,常量,方法描述等。对永生代的回收主要包括废弃常量和无用的类。
- 对象的内存分配主要在新生代的 Eden Space 和 Survivor Space 的 From Space(Survivor 目前存放对象的那一块),少数情况会直接分配到老生代。
- 当新生代的 Eden Space 和 From Space 空间不足时就会发生一次 GC,进行 GC 后,Eden Space 和 From Space 区的存活对象会被挪到 To Space,然后将 Eden Space 和 From Space 进行清理。
- 如果 To Space 无法足够存储某个对象,则将这个对象存储到老生代。
- 在进行 GC 后,使用的便是 Eden Space 和 To Space 了,如此反复循环
- 当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。默认情况下年龄到达 15 的对象会被移到老生代中。