Java垃圾回收算法和垃圾回收器
基本上 jvm内存回收有三种 基本算法
标记-清除
标记清除的算法最简单,主要是标记出来需要回收的对象,然后然后把这些对象在内存的信息清除。如何标记需要回收的对象,在上一篇文章里面已经有说明。
标记-清除-压缩
这个算法是在标记-清除的算法之上进行一下压缩空间,重新移动对象的过程。因为标记清除算法会导致很多的留下来的内存空间碎片,随着碎片的增多,严重影响内存读写的性能,所以在标记-清除之后,会对内存的碎片进行整理。最简单的整理就是把对象压缩到一边,留出另一边的空间。由于压缩空间需要一定的时间,会影响垃圾收集的时间。
标记-清除-复制
这个算法是吧内存分配为两个空间,一个空间(A)用来负责装载正常的对象信息,,另外一个内存空间(B)是垃圾回收用的。每次把空间A中存活的对象全部复制到空间B里面,在一次性的把空间A删除。这个算法在效率上比标记-清除-压缩高,但是需要两块空间,对内存要求比较大,内存的利用率比较低。适用于短生存期的对象,持续复制长生存期的对象则导致效率降低
由于现在的处理器都是多核的,处理器的性能得到了极大的提升,所以在此基础上有产生了几种垃圾收集算法。主要包括两种算法
- 并行标记清除
所谓并行,就是原来垃圾回收只是一个线程进行。现在创建多个垃圾回收线程。并行的进行标记和清除。比如把需要标记的对象平均分配到多个线程之后,当标记完成之后,多个线程进行清除。
- 并发标记清除
所谓并发,就是应用程序和垃圾回收可以同时执行。在标记清除算法中,在标记对象和清除对象,以及压缩对象的情况下是需要暂停应用的。那么并行标记清除压缩算法则是在标记清除压缩算法的基础上,把标记清除压缩算法分为以下几个过程
初始标记->并发标记->重新标记->并发清除->重置
以上几种算法是垃圾回收的基本算法,jvm垃圾回收就是在以上几种算法为基础的,在以上几种算法的基础上,java垃圾回收器可以分为以下几种:
- 串行收集器
用单线程处理所有垃圾回收工作,因为无需多线程交互,所以效率比较高。但是,也无法使用多处理器的优势,所以此收集器适合单处理器机器
单线程收集器。在目前多核服务器端运行的情况下,效率比较低。比较适合堆内存小的情况下使用。
- 并行收集器
用多线程处理所有垃圾回收工作,利用多核处理器的优势。但是如果线程数量过多,导致线程之间频繁调度,也会影响性能。一半并行收集的线程是处理器的个数。
“对吞吐量有高要求”,多CPU、对应用响应时间无要求的中、大型应用。举例:后台处理、科学计算。
- 并发收集器
并发收集器主要减少年老代的暂停时间,他在应用不停止的情况下使用独立的垃圾回收线程,跟踪可达对象。在每个年老代垃圾回收周期中,在收集初期并发收集器 会对整个应用进行简短的暂停(初始标记的过程),在收集中还会再暂停一次。第二次暂停会比第一次稍长(重新标记的过程),在此过程中多个线程同时进行垃圾回收工作。
并发收集器使用处理器换来短暂的停顿时间。在一个N个处理器的系统上,并发收集部分使用K/N个可用处理器进行回收,一般情况下1<=K<=N/4。
在只有一个处理器的主机上使用并发收集器,设置为incremental mode模式也可获得较短的停顿时间。
浮动垃圾:由于在应用运行的同时进行垃圾回收,所以有些垃圾可能在垃圾回收进行完成时产生,这样就造成了“Floating Garbage”,这些垃圾需要在下次垃圾回收周期时才能回收掉。所以,并发收集器一般需要20%的预留空间用于这些浮动垃圾。
Concurrent Mode Failure:并发收集器在应用运行时进行收集,所以需要保证堆在垃圾回收的这段时间有足够的空间供程序使用,否则,垃圾回收还未完成,堆空间先满了。这种情况下将会发生“并发模式失败”,此时整个应用将会暂停,进行垃圾回收。
并发收集器,在垃圾回收的时候采用并发标记清除算法的收集器
对响应时间要求高的,多CPU,大型应用。比如页面请求/web服务器。前端业务系统用的比较多。
我们以sun公司的hotspot虚拟机为例,hotspot采用的是分代回收算法,因为根据经验,一般80%的对象就是朝生夕灭,对象的生命期都很短。而根据对象的生命周期不同,可以划分出来几个区域,一部分区域的对象创建比较频繁,但是生命周期比较短,一部分区域对象生命周期比较长,还有一部分区域对象生命周期几乎和java虚拟机相同。
sunspot堆内存分为三个区域:

- 新生代(Young)
新生代包括两个区:Eden区和Survivor区,其中Survivor区一般也分成两块,简称Survivor1 Space 和 Survivor2 Space (或者From Space 和 To Space)。新生代通常存活时间较短,因此基于标记清除复制算法来进行回收,扫描出存活的对象,并复制到一块新的完全未使用的空间中,对应于新生代,就是在Eden和From或To之间copy。新生代采用空闲指针的方式来控制GC触发,指针保持最后一个分配的对象在新生代区间的位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC。当连续分配对象时,对象会逐渐从eden到Survior,最后到旧生代。
可以采用串行处理和并行处理器
- 老年代(Old)
在垃圾回收多次,如果对象仍然存活,并且新生代的空间不够,则对象会存放在老年代。
在老年代采用的是 标记清除压缩算法。因为老年代的对象一般存活时间比较长,每次标记清除之后,会有很多的零碎空间,这个就是所谓的浮动垃圾。当老年代的零碎空间不足以分配一个大的对象的时候,就会采用压缩算法。在压缩的时候,应用需要暂停。
可以采用串行处理,并行处理器,以及并发处理器。
- 持久代(Permanent)
这部分空间主要存放java方法区的数据以及启动类加载器加载的对象。这一部分对象通常不会被回收。所以持久代空间在默认的情况下是不会被垃圾回收的。
由于把内存空间分为三块,一般把新生代的GC称为minor GC ,把老年代的GC成为 full GC,所谓full gc 会先出发一次minor gc,然后在进行老年代的GC。
具体的过程如下:
首先想eden区申请分配空间,如果空间够,就直接进行分配,否则进行一次Minor GC。minor GC 首先会对Eden区的对象进行标记,标记出来存活的对象。然后把存活的对象copy到From空间。如果From空间足够,则回收eden区可回收的对象。如果from内存空间不够,则把From空间存活的对象复制到To区,如果TO区的内存空间也不够的话,则把To区存活的对象复制到老年代。如果老年代空间也不够(或者达到触发老年年垃圾回收条件的话)则触发一次full GC。
简单方向就是Eden->From->To->Old,如下图所示。

G1收集器:
将java的堆划分成多个大小固定的区域, 并跟踪这些区域里的垃圾堆积程度, 在后台维护一个优先队列表, 每次根据允许的收集时间,优先回收垃圾最多的区域。
区域划分以及优先级的区域回收, 保证了G1收集器在有限的时间内可以获得最高的收入效率。
Java垃圾回收算法和垃圾回收器的更多相关文章
- JVM 垃圾回收算法和垃圾回收器
JVM 垃圾回收算法和垃圾回收器. 一.垃圾回收的区域 栈:栈中的生命周期是跟随线程,所以一般不需要关注. 堆:堆中的对象是垃圾回收的重点. 方法区:这一块也会发生垃圾回收,不过这块的效率比较低,一般 ...
- java中的垃圾回收算法与垃圾回收器
常用的垃圾回收算法 标记-清除 标记清除算法是一种非移动式的回收算法,分为标记 清除 2个阶段,简而言之就是先标记出需要回收的对象,标记完成后再回收掉所有标记的内存对象,如下图 可见回收后图中被标记的 ...
- java架构之路-(12)JVM垃圾回收算法和垃圾回收器
接上次JVM虚拟机堆内存模型来继续说,上次我们主要说了什么时候可能把对象直接放在老年代,还有我们的可能性分析,提出GCroot根的概念.这次我们主要来说说垃圾回收所使用的的算法和我们的垃圾回收器,需要 ...
- 直通BAT必考题系列:JVM的4种垃圾回收算法、垃圾回收机制与总结
垃圾回收算法 1.标记清除 标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段. 在标记阶段首先通过根节点(GC Roots),标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象. ...
- Java垃圾回收算法和内存分配策略
垃圾回收算法和内存分配策略 Java垃圾回收 垃圾收集,也就是GC并不是Java的伴生物,而对于GC的所需要完成任务主要就是: 1.哪些内存是需要回收的? 2.何时去回收这些内存? 3.以何种方式去回 ...
- JVM学习总结二——垃圾回收算法
昨天总结了JVM内存分区相关的知识,这次我们将来了解下JVM的另一个核心知识点——垃圾回收算法.这一部分其实并不太难,如果对操作系统的内存处理算法有所了解,那么这部分算法其实只看名字就能明白,两者在原 ...
- 【转】Java学习---垃圾回收算法与 JVM 垃圾回收器综述
[原文]https://www.toutiao.com/i6593931841462338062/ 垃圾回收算法与 JVM 垃圾回收器综述 我们常说的垃圾回收算法可以分为两部分:对象的查找算法与真正的 ...
- 牛客网Java刷题知识点之垃圾回收算法过程、哪些内存需要回收、被标记需要清除对象的自我救赎、对象将根据存活的时间被分为:年轻代、年老代(Old Generation)、永久代、垃圾回收器的分类
不多说,直接上干货! 首先,大家要搞清楚,java里的内存是怎么分配的.详细见 牛客网Java刷题知识点之内存的划分(寄存器.本地方法区.方法区.栈内存和堆内存) 哪些内存需要回收 其实,一般是对堆内 ...
- (5)jvm垃圾回收器相关垃圾回收算法
引用计数法[原理]--->引用计数器是经典的也是最古老的垃圾收集防范.--->实现原理:对于对象A,只要有任何一个对象引用A,则计数器加1.当引用失效时,计数器减1.只要对象A的计数器值为 ...
随机推荐
- vmdk虚拟机转换为OVF模板,导入esxi
VMware WorkStation安装目录下,有一个OVFTool文件夹,例如我电脑上的路径为:D:\VMware\VMware\OVFTool.通过CMD进入到命令行模式,更改到该目录下,运行如下 ...
- 几个常见的Laravel报错及解决方法
报错:「Can't swap PDO instance while within transaction」 transactions >= 1) {throw new RuntimeExcept ...
- keepalived + nginx双主 实战
安装nginx nginx 下载地址 http://nginx.org/download/nginx-1.8.0.tar.gz 安装nginx的依赖关系 yum install pcre pcre-d ...
- mha的搭建步骤(一主一从架构)
所需脚本文件到这里下载:http://note.youdao.com/share/web/file.html?id=ae8b11a61f7a8aa7b52aac3fcf0c4b83&type= ...
- ACM题目————STL练习之 懒省事的小明(优先队列)
描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.小明决定把所有的果子合成一堆. 因为小明比较懒,为了省力气,小明开始想点子了: 每一 ...
- Oracle Hint 用法
正确的语法是: select /*+ index(x idx_t) */ * from t x where x.object_id=123 /*+ */ 和注释很像,比注释多了一个“+”,这就是 ...
- 3G中的A-GPS移动定位技术
位置业务(LBS,Location Based Service)是指移动网络通过特定的定位技术来获取移动终端的位置信息,从而为终端用户提供附加服务的一种增值业务,可广泛应用于紧急救援.导航追踪.运输调 ...
- css不同浏览器兼容性调试 --- 转自: [http://wo.115.com/?ct=detail&id=31733&bid=1018841]
css不同浏览器兼容性调试 IE6.0,IE7.0与Firefox的CSS兼容性问题1.DOCTYPE 影响 CSS 处理 2.FF: div 设置 margin-left, margin-right ...
- 利用反射及jdbc元数据实现通用的查询方法
---------------------------------------------------------------------------------------------------- ...
- Unity帧序列实时渲染脚本
该脚本会创建一个新相机进行录制,支持包含所有相机内容,完美解决跳帧问题,可自定义分辨率等参数,脚本会输出品质为100的jpg序列,基本无损. 但缺点是帧率始终是每秒100帧,必须压制时限制帧数. 而用 ...





