java垃圾回收算法实现原理,有两种,一个是引用计数法,一个是引用可达法。
引用计数法,每个对象有一个专门的空间维护一个引用计数器,当该对象被引用时,计数器加一,引用消失时则计数器减一,当该对象引用数为0时则回收该对象。这个算法有一个好处就是可以及时回收废弃的对象,而不用等到空间占满后在统一回收,但是其无法解决循环引用的情况。
而引用可达性分析法,则是选取一个root节点,通过该节点是否能够遍历到某个对象的方法来判断该对象是否被回收。root节点的选择通常是静态变量,native变量,常量等。
垃圾回收算法有三种
1.标记清除
也就是每次GC,会先扫描内存区标记存活对象,而后释放未被标记的对象空间。这种算法在工作时需要停止工作线程,再进行标记清除,同时会产生内存碎片,而且jvm需要维护一个内存空间表,用于分配内存空间。
2.复制清除
将内存区分为两个相同大小的区域,先在A上分配对象,当其分配满后,进行标记操作,而后将标记对象按照内存顺序复制到B区域中,最后将A区域全部清除。这种方式可以有效避免内存碎片的问题,但是复制操作会产生额外的耗时,当存活对象多时并不适合使用该算法,因为复制所产生的耗时会很长。因此这种算法适合对象存活时间短的情况。同时会造成一定的内存浪费。
3.标记整理
这种算法就是在标记清除的基础上为了避免内存碎片的产生而优化产生的算法。总的过程分为两步,分别是标记和整理。
java内存模型将内存区域分为,新生代、老年代、永久代。
新生代由于其对象存活时间短,且需要经常gc,因此采用效率较高的复制算法,其将内存区分为一个eden区和两个suvivor区,eden区和survivor区的比例是8:1,分配内存时先分配eden区,当eden区满时,使用复制算法进行gc,将存活对象复制到一个survivor区,当一个survivor区满时,将其存活对象复制到另一个区中,当对象存活时间大于某一阈值时,将其放入老年代。
老年代和永久代因为其存活对象时间长,因此使用标记清除或标记整理算法