我们来聊聊垃圾收集器中相关术语与新生代收集器
yuyutoo 2024-10-11 23:55 1 浏览 0 评论
垃圾收集算法为实现垃圾收集提供了强有力的理论支持,而垃圾收集器则是利用了垃圾收集算法去实现垃圾回收的实践落地。
那么和垃圾回收算法类似,Java 也提供了多款垃圾收集器,不同的垃圾收集器也有不同的特性以及适用场景,甚至不同的垃圾收集器之间还可能存在配合使用的关系,那么使用起来还是比较复杂的。下图展示了 Java 里面比较主流的垃圾收集器以及能够作用的内存区域。
其中 Serial、ParNe、Parallel Scavenge 是作用于新生代的,而 CMS、Serial Old 、Parallel Old 作用于老年代。G1 既可以作用于新生代,也可以作用于老年代。连线表示垃圾收集器之间可以配合使用。
理解这张图,这样在你配置垃圾收集器的时候,一来可以避免配置了不能配合的垃圾收集器,比如你配置 CMS 和 Parallel Scavenge 是不能配合的。二来你也能够知道各种垃圾收集器所能够作用的内存区域。
好,接下来在正式探讨垃圾收集器这个话题之前,我们先来普及几个术语。
Stop The World
Stop The World 简写为 STW,也叫全局停顿。在 Stop The World 这个状态下,所有的 Java代码会停止运行,native 代码可以继续运行,但是它没有办法和 JVM 进行交互。
那么 Stop The World 多半是由于垃圾回收导致的,另外也可能是由 Dump 线程死锁检查、Dump 堆等等导致的。
我们试想,为什么在垃圾收集的时候会有 Stop The World 呢?可以这样想,我们的应用在运行的时候会产生大量的对象。那么可以做这样的对比,我们假设应用程序里面所产生的对象好比我们的聚会,那么聚会的时候会产生垃圾,然后垃圾收集器是清洁工负责打扫垃圾。如果你的聚会不停止,不断地产生垃圾的话,那么清洁工永远都别想打扫干净这个场地,只有让大家都停止活动,才可能把屋子打扫干净。所以垃圾收集的时候会有 Stop The World。
那么 Stop The World 有什么危害呢?非常好理解,首先 Stop The World 的状态下,Java 代码都会停止运行。于是你的服务会停掉,你的请求不会有任何响应。直到应用从 Stop The World 状态出来之后,才会恢复响应。那么对于一些高可用的系统,比如有的应用它有主从模式,如果 Stop The World 持续的时间过长,甚至可能会引起主备切换。总而言之, Stop The World 对于生产环境的危害还是比较严重的,因此我们一般都需要尽量缩短 Stop The World 的时间。
并行收集 VS 并发收集
很多人搞不清楚并行和并发之间的区别,我们来看一下什么叫并行收集呢?
它指的是多个垃圾收集线程并行的工作,但是在垃圾收集线程工作的过程中,你的用户线程是处于等待状态的,也就是说在垃圾收集的阶段,有多个线程在回收垃圾,但是与此同时你的业务线程都在等待中。
那么什么是并发收集呢?它指的是你的用户线程和垃圾收集线程同时工作,这个叫并发收集。
吞吐量
吞吐量指的是 CPU 用于运行用户代码的时间和 CPU 总消耗时间的比值。
计算公式:吞吐量=运行用户代码的时间 /(运行代码的时间+垃圾收集时间)。
举个例子,有一个 JVM 总共运行了 100 分钟,垃圾收集花费了 1 分钟,那么吞吐量就是 99% 。
好,了解这几个术语之后,正式探讨 Java 里面的垃圾收集器。
Serial 收集器
先来探讨新生代里面收集器。
第一款垃圾收集器叫 Serial 收集器,也叫串行收集器。那么Serial 收集器是最基本的收集器,也是发展历史最悠久的收集器。它使用的是复制算法。执行过程大概如下图所示:
用户线程运行到一个安全点之后全部暂停,然后由一个垃圾收集线程去回收,垃圾回收完成之后,用户线程才能继续执行。
那么这个垃圾收集器有哪些特点呢?
首先这个垃圾收集器是单线程的。
第二,简单高效。简单很好理解,单线程的当然比较简单了。那么高效是什么意思呢?这里所谓的高效是和其他收集器单个线程的工作效率下相比的,由于 Serial 收集器是单线程的,所以它没有和其他线程交互的开销,专心去做垃圾收集,因此它相对其他的垃圾收集器,单线程的工作效率会相对高一些。
第三,用这个垃圾收集器回收垃圾的时候,工作线程全程暂停,直到收集结束,也就是说整个垃圾收集线程一直处于 Stop The World 的状态。
Serial 收集器适用于什么样的场景呢?
第一,一般来说,它比较适合用来运行一些客户端程序,那么事实上,当你的项目使用 Client 模式运行的时候,默认使用的就是 Serial 收集器。比如你有一个应用在启动的时候,java -client -java xxx,这样使用的就是 Serial 收集器
第二,它比较适合运行在单核机器上,比如说一些嵌入式低性能的机器上。
ParNew 收集器
ParNew 收集器可以认为是 Serial 收集器的多线程版本。因为这个收集器除使用多线程以外,其他特性和 Serial 收集器都是一样的。比如针对 ParNew 收集集的一些 JVM 参数、Stop The World 的表现以及垃圾数据算法都和 Serial 是一致的。ParNew 收集器集的执行过程大致如下图所示:
用户线程执行到安全点之后暂停,然后会有多个垃圾数据线程去回收,垃圾回收完之后,用户线程继续执行。
ParNew 收集器的特点是多线程。另外它可以使用这个参数: -XX:ParallelGCThreads 去设置垃圾收集的线程数,在不同运行环境下,根据 CPU 的核数,开启不同的线程数,从而达到最优的垃圾收集效果。
在多 CPU 时,比 Serial 收集效率高。同时收集过程暂停所有应用程序线程,单 CPU 时比 Serial 效率差。
ParNew 收集器主要用来和 CMS 配合使用。同时运行在Server模式下的虚拟机中首选的新生代收集器。
Parallel Scavenge 收集器
和 ParNew 收集器一样,Parallel Scavenge 收集器也是运行在新生代区域,属于多线程的收集器,但不同的是,ParNew 收集器是通过控制垃圾回收的线程数来进行参数调整,而 Parallel Scavenge 收集器更关心的是程序运行的吞吐量,所以也被称为是吞吐量优先收集器,即一段时间内,用户代码运行时间占总运行时间的百分比。并且采用的算法是复制算法,执行过程和ParNew 也是类似的。
Parallel Scavenge 收集器特点有哪些呢?
首先使用 Parallel Scavenge 收集器可以达到一个可控的吞吐量,Parallel Scavenge 收集器提供了两个参数去控制吞吐量。
第一,-XX:MaxGCPauseMillis:最大垃圾收集停顿时间,是一个大于 0 的毫秒数,比如你可以配置这个时间等于 100 毫秒,收集器将回收时间尽量控制在这个设定值之内,但是也不保证绝对不超过这个值。同时需要注意的是在同样的情况下,回收时间与回收次数是成反比的,回收时间越小,相应的回收次数就会增多,所以这个值并不是越小越好。
第二,-XX:GCTimeRatio:它用来设置吞吐量的大小,取值是(0, 100)之间的整数,表示垃圾收集时间占总时间的比率。假设我们把 GCTimeRatio 的值设成 n,那么系统花费在垃圾收集的时间不会超过 1/(1+n)。
那么 Parallel Scavenge 除提供了两个参数去控制存储量以外,还提供一个自适应垃圾收集的机制,你可以使用这个参数:-XX:+UseAdaptiveSizePolicy 去开启自适应垃圾收集策略,一旦开启自适应策略之后,就不需要设置新生代的大小 Eden 和 Survivor 区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了。虚拟机它会自动地根据系统的运行状况去收集性的监控信息,然后动态地调整这些参数,从而实现最优的停顿时间以及最高的吞吐量。
这种调节方式称为 GC 自适应的调节策略(GC Ergonomics)。自适应调节策略也是 Parallel Scavenge 收集器与 ParNew 收集器的一个重要区别。
所以经过分析,Parallel Scavenge 收集器存在一定的智能性,那么 Parallel Scavenge 适用于什么样的场景呢?它适用于比较注重吞吐量的场景。
简单总结一下本课时,本课时我们主要学习了垃圾收集器相关的术语以及新生代中三个收集器,详细介绍了使用场景、特点以及使用的场景。
相关推荐
- jQuery VS AngularJS 你更钟爱哪个?
-
在这一次的Web开发教程中,我会尽力解答有关于jQuery和AngularJS的两个非常常见的问题,即jQuery和AngularJS之间的区别是什么?也就是说jQueryVSAngularJS?...
- Jquery实时校验,指定长度的「负小数」,小数位未满末尾补0
-
在可以输入【负小数】的输入框获取到焦点时,移除千位分隔符,在输入数据时,实时校验输入内容是否正确,失去焦点后,添加千位分隔符格式化数字。同时小数位未满时末尾补0。HTML代码...
- 如何在pbootCMS前台调用自定义表单?pbootCMS自定义调用代码示例
-
要在pbootCMS前台调用自定义表单,您需要在后台创建表单并为其添加字段,然后在前台模板文件中添加相关代码,如提交按钮和表单验证代码。您还可以自定义表单数据的存储位置、添加文件上传字段、日期选择器、...
- 编程技巧:Jquery实时验证,指定长度的「负小数」
-
为了保障【负小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【负小数】的方法。HTML代码<inputtype="text"class="forc...
- 一篇文章带你用jquery mobile设计颜色拾取器
-
【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...
- 编程技巧:Jquery实时验证,指定长度的「正小数」
-
为了保障【正小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【正小数】的方法。HTML做成方法<inputtype="text"class="fo...
- jquery.validate检查数组全部验证
-
问题:html中有多个name[],每个参数都要进行验证是否为空,这个时候直接用required:true话,不能全部验证,只要这个数组中有一个有值就可以通过的。解决方法使用addmethod...
- Vue进阶(幺叁肆):npm查看包版本信息
-
第一种方式npmviewjqueryversions这种方式可以查看npm服务器上所有的...
- layui中使用lay-verify进行条件校验
-
一、layui的校验很简单,主要有以下步骤:1.在form表单内加上class="layui-form"2.在提交按钮上加上lay-submit3.在想要校验的标签,加上lay-...
- jQuery是什么?如何使用? jquery是什么功能组件
-
jQuery于2006年1月由JohnResig在BarCampNYC首次发布。它目前由TimmyWilson领导,并由一组开发人员维护。jQuery是一个JavaScript库,它简化了客户...
- django框架的表单form的理解和用法-9
-
表单呈现...
- jquery对上传文件的检测判断 jquery实现文件上传
-
总体思路:在前端使用jquery对上传文件做部分初步的判断,验证通过的文件利用ajaxFileUpload上传到服务器端,并将文件的存储路径保存到数据库。<asp:FileUploadI...
- Nodejs之MEAN栈开发(四)-- form验证及图片上传
-
这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能。开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/R...
- 大数据开发基础之JAVA jquery 大数据java实战
-
上一篇我们讲解了JAVAscript的基础知识、特点及基本语法以及组成及基本用途,本期就给大家带来了JAVAweb的第二个知识点jquery,大数据开发基础之JAVAjquery,这是本篇文章的主要...
- 推荐四个开源的jQuery可视化表单设计器
-
jquery开源在线表单拖拉设计器formBuilder(推荐)jQueryformBuilder是一个开源的WEB在线html表单设计器,开发人员可以通过拖拉实现一个可视化的表单。支持表单常用控件...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)