Java垃圾回收机制

来源:互联网 发布:数据库数据抓取 编辑:程序博客网 时间:2024/06/05 23:06

为什么要垃圾回收

由于在Java中,程序员不能够像在C/C++一样直接delete()对象,就会导致一些无用对象在内存中积累,可能会发生内存溢出。所以需要一个机制,识别并且清理垃圾。
Java的垃圾回收机制使程序员从内存管理中释放出来,可以专心的处理业务逻辑,也不会出现C/C++中忘记回收内存导致程序异常的现象了。

常用的垃圾回收算法

引用计数法

对于一个对象A,如果有一个对象引用了A,则计数器加油,如果引用失效,计数器减一,只要计数器值为零,就认为其不可能被使用。
主要问题是无法解决循环引用的问题

标记清除法

两个阶段:
1)从根节点出发,标记所有可达对象
2)删除所有未被标记的对象
问题:会产生大量的空间碎片

复制算法

将原有的内存空间分为两块,每次只使用一块,在进行垃圾回收时,将正在使用内存中的存活对象移动到未被使用的内存中,清除正在使用内存中的对象,交换两个内存的角色,完成垃圾回收
问题:将系统的内存减半。

标记压缩法

从根节点出发,标记存活的对象,将所有的陪标记的对象压缩到内存的一端,最后清理边界外的所有内存。这避免了内存碎片的形成,但是前提条件是存活的对象多,否则性能会很差

分代算法

上面中算法,各有各的优缺点,在Java的垃圾回收中,如果能够根据特点选择不同的算法,则会有更好的结果,分代算法就是基这个思想的。

他将内存区分为几块,根据内存区间的特点使用不同的算法
1)新生代:死亡率高  ,使用复制算法
2)老年代:存活率高 , 使用标记压缩算法,标记清除算法

新生代中的复制算法

新生代分为:
1)eden空间
2)from空间
3)to 空间
from和to也被称为surivor空间(幸存者空间,用来存放未被回收的对象)

在垃圾回收时,eden空间中存活的对象被复制到未被使用的surivor空间(假设是to),from中存活的对象也会复制到to中(也可能会直接到老年代,看情况),剩下的就是垃圾对象,直接清理,最后from和to交换角色

(为了支持高频率的新生代回收,虚拟机可能会使用一个叫卡表的数据结构,原理有点像跳表)


问题来了:如何判断一个对象是垃圾?垃圾回收仅仅是回收不用的对象?
垃圾回收时的停顿现象是什么?
0 0
原创粉丝点击