简介:
当对象不在使用的时候,就需要释放内存,以供新的对象使用,此时就需要了解对象内存释放的机制。
判断是否回收的方法
1. 引用计数法:
给对象增加一个引用计数器,每当有一个地方引用它是,计数器就+1,当引用失效时,计数器就-1,任何时刻计数器为 0 的对象就是不能再被使用的,即对象已“死”。
引用计数法实现简单,判定效率也比较高,Python 语言就是采用的这种算法进行内存管理。
但是,在主流的 JVM 中并没有被使用,是因为引用计数器无法解决对象循环引用的问题。
2. GC Root Tracing算法(可达性分析算法)
从GC Roots出发,所有可达的对象都是存活的对象,而不可达的对象都是垃圾。
可作为 GC Roots 的对象包含以下几种:
a.虚拟机栈中引用的对象
b.方法区中静态属性引用的对象
c.方法区中常量引用的对象
d.本地方法栈中引用的对象
如何进行垃圾回收
首先认识一下三种算法
主要有三种:标记删除算法、复制算法、标记的压缩算法。
1. 标记清除算法
先标记,统一清除,会存在内存碎片问题。
2. 复制算法
为了解决“标记-清除”效率问题,它将内存按容量大小分为相等的两块,每次使用一块,当这块内存进行垃圾回收时,此区域存活的对象复制到另一块上面,然后把已经使用过得内存进行清理。这样的好处是每次仅对半块区域进行内存回收,内存分配时也不会出现内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配即可。
3.标记的压缩算法
是标记清除算法的优化版,同样需要经历两个阶段,分别是标记结算、压缩阶段。在标记阶段,从 GC Roots 引用集合触发去标记所有对象。在压缩阶段,将其所有存活的对象压缩在内存的一边,再清理边界外的空间。
分代思想
所谓分代思想,就是根据 JVM 不同的内存区域,采用不同的垃圾回收算法,例如,对于存活对象少的新生代区域,就比较适合复制算法;对于老年代有存活对象多的区域,就比较适合采用标记压缩算法。
分区思想
整个 JVM 内存空间可以划分成连续的的不同小区间。每个小区间独立使用更加灵活的控制回收分区数量以及回收时间。