深入理解JVM(5)——HotSpot垃圾收集器详解
HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器。根据新生代和老年代各自的特点,我们应该分别为它们选择不同的收集器,以提升垃圾回收效率。
新生代垃圾收集器:
- Serial垃圾收集器
a) 单线程:只开启一条GC线程进行垃圾回收,并且在垃圾回收过程中停止一切用户线程,从而用户的请求或图形化界面会出现卡顿。
b) 适合客户端应用
c) 简单高效:由于Serial收集器只有一条GC线程,因此避免了线程切换的开销,从而简单高效。
d) 采用“复制”算法
- ParNew垃圾收集器:ParNew是Serial的多线程版本
a) 多线程并行执行:ParNew由多条GC线程并行地进行垃圾清理。但清理过程仍然需要停止一切用户线程。但由于有多条GC线程同时清理,清理速度比Serial有一定的提升。
b) 适合多CPU的服务器环境
c) 采用“复制算法”
d) 追求“降低停顿时间”:和Serial相比,ParNew使用多线程的目的就是缩短垃圾收集时间,从而减少用户线程被停顿的时间。
e) 和Serial的对比:ParNew和Serial唯一的区别就是使用了多线程进行垃圾回收,在多CPU的环境下性能比Serial会有一定程度的提升;但线程切换需要额外的开销,因此在单CPU环境中表现不如Serial。
- Parallel Scavenge垃圾收集器:Parallel Scavenge和ParNew一样都是多线程、新生代收集器,都使用“复制”算法进行垃圾回收。但它们有个巨大的不同点:ParNew收集器追求降低用户线程的停顿时间,因此适合交互式应用;而Parallel Scavenge追求CPU吞吐量,能够在较短的时间内完成指定任务,因此适合没有交互的后台计算。
a) 什么是吞吐量:吞吐量是指用户线程运行时间占CPU总时间的比例。CPU总时间包括:用户线程运行时间 和 GC线程运行的时间。因此,吞吐量越高表示用户线程运行时间越长,从而用户线程能够被快速处理完。
b) 降低停顿时间的两种方式
i. 在多CPU环境中使用多条GC线程,从而垃圾回收的时间减少,从而用户线程停顿的时间也减少
ii. 实现GC线程与用户线程并发执行。所谓并发,就是用户线程与GC线程交替执行,从而每次停顿的时间会减少,用户感受到的停顿感降低,但线程之间不断切换意味着需要额外的开销,从而垃圾回收和用户线程的总时间将会延长。
老年代垃圾收集器
- Serial Old垃圾收集器:
a) Serial Old收集器是Serial的老年代版本
b) 单线程,在垃圾收集时只启动一条GC线程
c) 适合客户端应用
d) 它们唯一的区别就是Serial Old工作在老年代,使用“标记-整理”算法;而Serial工作在新生代,使用“复制”算法。
- ParNew Old垃圾收集器:Parallel Old收集器是Parallel Scavenge的老年代版本,一般它们搭配使用,追求CPU吞吐量。它们在垃圾收集时都是由多条GC线程并行执行,并停止一切用户线程。因此,由于在垃圾清理过程中没有使垃圾收集和用户线程并行执行,因此它们是追求吞吐量的垃圾收集器。
- CMS垃圾收集器:CMS收集器是一款追求停顿时间的老年代收集器,它在垃圾收集时使得用户线程和GC线程并行执行,因此在垃圾收集过程中用户也不会感受到明显的卡顿。但用户线程和GC线程之间不停地切换会有额外的开销,因此垃圾回收总时间就会被延长。
- CMS的缺点:
a) 吞吐量:由于CMS在垃圾收集过程使用用户线程和GC线程并行执行,从而线程切换会有额外开销,因此CPU吞吐量就不如在垃圾收集过程中停止一切用户线程的方式来的高。
b) 无法处理浮动垃圾,导致频繁的FullGC:由于垃圾清除过程中,用户线程和GC线程并发执行,也就是用户线程仍在执行,那么在执行过程中会产生垃圾,这些垃圾称为“浮动垃圾”。 如果CMS在垃圾清理过程中,用户线程需要在老年代中分配内存时发现空间不足时,就需要再次发起Full GC,而此时CMS正在进行清除工作,因此此时只能由Serial Old临时对老年代进行一次Full GC。
c) 使用标记-清除算法或者是标记-整理算法容易产生碎片空间
通用垃圾收集—G1垃圾收集器:目前为止最牛逼的垃圾收集器
- G1垃圾收集器的特点:
a) 追求停顿时间
b) 多线程GC
c) 面向服务器端使用
d) 标记-整理和复制算法合并,不会产生碎片内存
e) 可对整个堆内存进行垃圾回收
f) 可以预测停顿时间
- G1垃圾收集器的内存模型:G1垃圾收集器没有新生代和老年代的概念了,而是将堆划分为一块块独立的Region(区域)。当要进行垃圾收集时,首先估计每个Region中的垃圾数量,每次都从垃圾回收价值最大的Region开始回收,因此可以获得最大的回收效率。
- Remembered Set:一个对象和它内部所引用的对象可能不在同一个Region中,那么当垃圾回收时,每个Region都有一个Remembered Set,用于记录本区域中所有对象引用的对象所在的区域,从而在进行可达性分析时,只要在GC Roots中再加上Remembered Set即可防止对所有堆内存的遍历。
深入理解JVM(5)——HotSpot垃圾收集器详解的更多相关文章
- 深入理解Java虚拟机(四)——HotSpot垃圾收集器详解
垃圾收集器 新生代收集器 1.Serial收集器 特点: 单线程工作,收集的时候就会停止其他所有工作线程,用户不可知不可控,会使得用户界面出现停顿. 简单高效,是所有收集器中额外内存消耗最少的. 没有 ...
- 理解JVM之垃圾收集器详解
前言 垃圾收集器作为内存回收的具体表现,Java虚拟机规范并未对垃圾收集器的实现做规定,因而不同版本的虚拟机有很大区别,因而我们在这里主要讨论基于Sun HotSpot虚拟机1.6版本Update22 ...
- 深入理解JVM虚拟机-2垃圾收集器
这里讨论的收集器基于JDK 1.7 Update 14之后的HotSpot虚拟机. 如果两个收集器之间存在连线,说明可以搭配使用.虚拟机所处的区域,则表示它是属于新生代收集器还是年老代收集器.在这里我 ...
- 04-JVM垃圾收集器详解
1.垃圾收集器的种类 垃圾收集算法是内存回收的方法论,垃圾收集器是内存回收的具体实现工具.目前没有万能的垃圾收集器,需要根据具体的应用场景选择合适的垃圾收集器. 1.1Serial收集器(-XX:+U ...
- java - GC垃圾收集器详解(三)
以前收集器的特点 年轻代和老年代是各自独立且连续的内存块 年轻代收集必须使用单个eden+S0+S1进行复制算法 老年代收集扫描整个老年代区域 都是以尽可能少而快速地执行GC为设计原则 G1是什么 G ...
- java - GC垃圾收集器详解(二)
CMS收集器 CMS收集器(ConcurrentMarkSweep:并发标记清除)是一种以获取最短回收停顿时间为目标的收集器. 适合应用在互联网站或者B/S系统的服务器上,这类应用尤其重视服务器的响应 ...
- java - GC垃圾收集器详解(一)
概要 该图标记了在jdk体系中所使用到的垃圾收集器及对应的关系图.图片上方为年轻代的垃圾收集器而图片下方是老年代的垃圾收集器.当选择某一个区域的垃圾收集器时会自动选择另外一个区域的另一个垃圾收集器.例 ...
- 【JVM】JVM中的垃圾收集器
垃圾收集器组合 Serial+Serial Old Serial+CMS ParNew+CMS ParNew+Serial Old Paralle Scavenge + Serial Old Para ...
- Java 虚拟机系列二:垃圾收集机制详解,动图帮你理解
前言 上篇文章已经给大家介绍了 JVM 的架构和运行时数据区 (内存区域),本篇文章将给大家介绍 JVM 的重点内容--垃圾收集.众所周知,相比 C / C++ 等语言,Java 可以省去手动管理内存 ...
随机推荐
- VS2017+mysql5.7 连接数据库生成实体
参考:https://www.cnblogs.com/RushPasser/p/5438334.html 下载:https://share.weiyun.com/5rM4FrG mysql-for-v ...
- Go语言之闭包
闭包的最初目的是为了减少全局变量,在函数调用过程中,隐式的传递共享变量. 但这样的编辑,带来的坏处是不够直接清晰. 所以,如非必要,不要使用. 对象是附有行为的数据,它在类中集中定义, 而闭包是附有数 ...
- 安装和强行卸载fuse
先卸载 yum list fuse yum --setopt=tsflags=noscripts remove fuse.x86_64 安装 yum install automake gcc-c++ ...
- [转] JavaScript 之 ArrayBuffer
JS里的ArrayBuffer 还记得某个晚上在做 canvas 像素级操作,发现存储像素的数据格式并不是Array类型,而是ArrayBuffer,心想这是什么鬼?后来查了一些资料,发现自己这半年来 ...
- noi2016旷野大作战
玩了差不多两个小时61分 大概第9个点可以再拿5-6分 但是挺麻烦的并不想搞.. 这道题还是比较考验智商的??以及对那个特殊的ln函数的应用 感觉题目出的挺好的 看了题解 发现第4个点的确我应该想不到 ...
- (三)apache的安装与配置
一.安装: 推荐使用cygwin自带的Setup.exe.带来的好处不言而喻,所有安装的程序都是经过测试的,这样确保你不会把宝贵的时间浪费来毫无意义的劳动上. 在安装程序中选择两个包就行了(分别是ap ...
- postgresql 查询某一个表中的所有字段
select * from information_schema.columns where table_schema='public' and table_name='表名称 ';
- awk命令的用法实战
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAn8AAADvCAIAAAAM1SXGAAAgAElEQVR4nO2dz8s125XXHx9oTXMHUZ
- net core体系-API-1Ocelot-(2)继续深入
简单的说Ocelot是一个用.NET Core实现并且开源的API网关技术.可能你又要问了,什么是API网关技术呢?Ocelot又有什么特别呢?我们又该如何集成到我们的asp.net core程序中呢 ...
- Python学习(十七)—— 数据库(二)
转载自http://www.cnblogs.com/linhaifeng/articles/7356064.html 一. 数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中, ...