一 判断对象是否死亡
1引用计数算法
- 给对象加一个计数器,在对象引用时加1,取消引用时减1,当计数器为0 时,即不可以再用 python
- 很难解决对象之间的循环引用
2跟搜索算法
- 使用一些类的GC roots的对作为起点开始向下搜索,当对象到GC roots没有任何路径,说明此对象死亡
- 可以作为Gcroot对象的有
- 虚拟机栈中
- 方法区中的静态属性和常量
- 本地方法栈
3引用
- 强引用
类似与 Object obj=new Object();只要强引用存在,就永远不会别回收。
- 软引用
有用但是非必须的对象,内存溢出异常时,会对这些对象列入回收范围中进行二次回收
- 弱引用
只能生存到下一次垃圾回收之前
- 虚引用
唯一作用 ,回收时,收到系统一个通知
4对象逃脱死亡
finalize 是用来逃脱的最后方法,只要与任意的 gcroots建立连接就行
二 垃圾收集算法
1标记-清除算法
首先标记处所要清除的对象,随后对这些对象进行清除 缺点
- 效率低
- 会产生大量的空间碎片,使新建对象时没有足够的空间而在此调用垃圾回收机制
2复制算法
将内存分为两块,当一块内存用完了,就将活着的放到新的内存中,把原来的内存清掉。
- 若存活率高的话效率就会降低
3标记-整理算法
先标记,然后将存活的移动到另一端,清理掉边界以外的内存。
4分代回收算法
将堆分为不同的代,新生代,老年代,然后依据不同代来采用不同的回收算法
分代回收算法理解
我是一个普通的Java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我18岁的时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的,我在这里也认识了很多人。在年老代里,我生活了20年(每次GC加一岁),然后被回收。
三 垃圾收集器
serial收集器
- 单线程
- 使用时必须暂停其他所有的工作线程
- 简单高效
parnew收集器
-多线程 -新生代收集器
parallel Scavenge收集器
- 多线程
- 复制算法
- 可控吞吐量(吞吐量=运行代码所用时间/(运行代码所用时间+来及回收机制时间))
Serial Old收集器
- 收集老年代的版本
- 单线程
- 标记整理
SMS收集器
- 目的为了获取最短回收停顿时间位目标的收集器
- 标记清除算法
G1收集器
- 标记整理算法
- 精确的控制卡顿