java垃圾回收算法

1)引用计数法

这是最经典和最古老的一种,它的工作原理是为每个对象配备一个计数器,只有这个对象被引用了,引用计数器就加1,当引用失效时,计数器减一,只要计数器为0,意味着不再被使用,于是该对象就可以被回收了。

优点:实现简单;

缺点:无法处理循环引用情况。即有应该被回收的垃圾对象A、B,他们互相引用,除此之外无其他引用,然而他们计数器值不是0,因此无法回收,从而造成内存泄漏。

2)标记-清除算法

这个算法将垃圾回收分为两个阶段,标记阶段和清除阶段,在标记阶段,首先通过根结点,标记所有从根结点开始的可达对象,因此未被标记的对象就是未被引用的垃圾对象,即使存在上面那样的相互引用的垃圾对象,但是由于从根结点出发无法到达,因此他们也未被标记。然后,在清除阶段,清除所有未被标记的对象。

优点:处理了循环引用的问题;

缺点:回收后的空间往往是不连续的,容易产生空间碎片。如此,在对象的堆空间分配时,尤其是大对象,不连续的内存空间的工作效率是明显比连续的低的。

3)复制算法

算法思想是把原来的可用的内存等分为两块,然后每次只是使用其中一块,在垃圾回收的时候,就把正在使用的那块内存里的存活的对象移动到另一块未被使用的内存中,然后清除原来那块,再把存活对象整体移动过来,如此就克服了空间不连续的缺点。

在Java的堆新生代串行垃圾回收器中就应用了该算法,新生代分为eden空间、from空间和to空间这3个部分。eden空间充当每次被使用的空间,而from和to空间就是移动的缓存空间。

优点:适用于新生代,因为新生代中垃圾对象往往多余存活对象,因此复制算法效果好些。

缺点:虽然比标记清除算法高效些,然后,系统内存折半使用,终究是一大缺陷。

4)标记-压缩算法

老年代是不太适合用复制算法的,因为大部分都是存活对象,复制成本高。因此,在标记-清除算法基础上改进,标记阶段一样,而在清除阶段,把所有存活的对象压缩驱赶到内存的一端,使得它连续起来。然后再清除其他空间。如此就避免了碎片空间的产生。

5)增量算法

对于大部分垃圾回收算法而言,由于垃圾回收时,除了垃圾回收线程外,进程其他线程都会高高挂起,直等到垃圾回收完成。然而,如果,你垃圾回收很久还没结束,用户就会等得不耐烦了。例如,在Android应用中,如果界面响应时间超过5s还没有反应,那就出现ANR,系统提示要不要停止该应用了。因此,为了避免影响用户体验,一次性完成所有垃圾的清理不太明智的,增量算法的思想则是让垃圾回收线程与其他应用线程交替执行,每次垃圾回收线程只是清理一小块内存。如此,减少系统停顿时间。

缺点是:因为线程切换和上下文切换,垃圾回收成本上升了,造成系统吞吐量下降。

总结:以上5种算法各有优劣,只在JVM中用一种显然是不好的,
最好的办法是对垃圾回收器分年代,分为新生代和老年代。一个对象新创建的时候进入到新生代,然后垃圾回收几次后,该对象依然存活,于是就放入老年代。新生代多用复制算法,老年代多用标机压缩算法。然后整个垃圾回收器的工作线程是用增量算法,时间轮转片执行。此谓之分代思想!

java垃圾回收算法,布布扣,bubuko.com

时间: 2024-08-06 07:59:15

java垃圾回收算法的相关文章

深入理解java垃圾回收算法

Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这三个区域的内存分配和回收都具有确定性.垃圾回收重点关注的是堆和方法区部分的内存. 常用的垃圾回收算法有: (1).引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不再被使用的,垃

java垃圾回收算法和垃圾收集器

垃圾收集算法.垃圾回收算法.java垃圾收集器 目录1. 垃圾收集算法1)引用计数法2)根搜索法2. 垃圾回收算法1)复制算法2)标记-清除算法3)标记-整理算法4)分代收集算法3. java垃圾收集器新生代GC器:1)Serial垃圾收集器2)ParNew垃圾收集器3)Parallel Scavenge垃圾收集器老年代GC器1)Serial和Parallel Scavenge都有对应的老年代版本2)CMS垃圾收集器4.java对象的内存分配位置5.java TLAB 1. 垃圾收集算法 1)引

java垃圾回收算法之-标记清除

博文在我的csdn博客中: http://blog.csdn.net/linsongbin1/article/details/51577310

JAVA虚拟机垃圾回收算法原理

除了释放不再被引用的对象外,垃圾收集器还要处理堆碎块.新的对象分配了空间,不再被引用的对象被释放,所以堆内存的空闲位置介于活动的对象之间.请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的总空闲空间是足够的.这是因为,堆中没有连续的空闲空间放得下新的对象. 垃圾收集器算法 任何垃圾回收算法都必须做两件事,首先,它必须检测出垃圾对象.其次,它必须回收垃圾对象所使用的堆空间并还给程序.从根对象开始,任何可以被触及的对象都被认为是“活动的”对象(如果正在运行的程序可以访问到根对象和某个对象之间

Java GC 垃圾回收算法 内存分配

垃圾回收(Garbage Collection, GC)是Java不同于c与c++的重要特性之一. 他帮助Java自动清空堆中不再使用的对象. 由于不需要手动释放内存,程序员在编程中也可以减少犯错的机会. 利用垃圾回收,程序员可以避免一些指针和内存泄露相关的bug(这一类bug通常很隐蔽). 垃圾回收实际上是将原本属于程序员的责任转移给计算机. GC需要完成的3件事情: 哪些内存需要回收 什么时候回收 如何回收 1 回收那些对象? 在Java中采用可达性分析算法来判定对象是否存活,是否可以被回收

Java内存回收(2)——垃圾回收算法

如果还没看过第一篇的朋友请移步:JAVA内存回收(1)-深入浅出Java垃圾回收机制 任何垃圾收集算法必须完成两件事情.首先,它必须检测出垃圾对象.其次,它必须回收垃圾对象所占用的堆空间并使之对程序重新可用. 垃圾检测通常通过定义一个根引用集并计算其可达对象集的方式来实现.一个对象,如果可以通过某条始于根引用的引用路径而被执行程序访问到的话,则称其为可达的(reachable).对程序而言,根引用始终是可以访问的.一个对象如果是可达的,则称其为活动对象:否则就被称为垃圾,因为它对程序的未来执行不

Java中的垃圾回收算法

1)垃圾回收的两个关键要素: 发现无用对象. 回收无用对象的内存空间. 2)6种垃圾回收算法 引用计数法,tracing 算法,compacting算法,copying 算法,generation算法,adaptive算法. 3)detail: 引用计数法(Reference Counting Collector)引用计数法是唯一没有使用根集的垃圾回收的法,该算法使用引用计数器来区分存活对象和不使用的对象.一般来说,堆中的每个对象对应一个引用计数器.当每一次创建一个对象并赋给一个变量时,引用计数

java虚拟机学习-JVM调优总结-新一代的垃圾回收算法(11)

垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full GC所带来的应用暂停.在一些对实时性要求很高的应用场景下,GC暂停所带来的请求堆积和请求失败是无法接受的.这类应用可能要求请求的返回时间在几百甚至几十毫秒以内,如果分代垃圾回收方式要达到这个指标,只能把最大堆的设置限制在一个相对较小范围内,但是这样有限制了应用本身的处理能力,同样也是不可接收的. 分代垃圾回收方式确实也考虑了实时性要求而

(转)《深入理解java虚拟机》学习笔记3——垃圾回收算法

Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此这三个区域的内存分配和回收都具有确定性.垃圾回收重点关注的是堆和方法区部分的内存. 常用的垃圾回收算法有: (1).引用计数算法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器都为0的对象就是不再被使用的,垃