serial 垃圾回收器

  serial回收器是jvm的Clint模式下的默认垃圾收集器。它是单线程采用复制算法(垃圾回收算法详解)来进行垃圾回收,负责年轻代的回收,需要stw(算法详解里有解释)。对比其他垃圾回收器,在多核资源十分丰富的服务器环境下,它的效率并不高,但它在资源匮乏环境下的垃圾回收的效率是很能打的,在单核服务器,或者cpu核数小于服务器当前运行服务数需要竞争cpu资源的时候,建议使用serial回收器。

serialOld 垃圾回收器

  serial的老年代版本,使用压缩算法(标记-滑动算法,标记整理算法)与parNew和cms搭配进行垃圾收集。parNew负责年轻代,cms负责老年代,当出现Concurrent Mode Failure异常或者老年代零碎空间最大不够新对象使用时使用serialOld进行full gc。

parNew

  serialOld回收器的多线程版本,采用复制算法。可以使用-XX:+UseParNewGC开启,只能回收年轻代。支持并发

Parallel Scavenge

   一个关注吞吐量的回收器,所谓吞吐量,就是用户线程执行的时间/回收垃圾的时间+用户线程执行的时间。使用的是复制算法。支持并发。可以通过-XX:MaxGCPauseMillis设置最大垃圾收集时的停顿时间,单位为毫秒
以下是常见命令
-XX:+UseParallelGC
   年轻代使用ParallelGC垃圾回收器,老年代使用串行回收器。
-XX:+UseParallelOldGC
   年轻代使用ParallelGC垃圾回收器,老年代使用ParallelOldGC垃圾回收器。
-XX:MaxGCPauseMillis
   设置最大的垃圾收集时的停顿时间,单位为毫秒
   需要注意的时,ParallelGC为了达到设置的停顿时间,可能会调整堆大小或其他的参数,如果堆的大小设置的较小,就会导致GC工作变得很频繁,反而可能会影响到性能。
   该参数使用需谨慎。
-XX:GCTimeRatio
   设置垃圾回收时间占程序运行时间的百分比,公式为1/(1+n)。
   它的值为0~100之间的数字,默认值为99,也就是垃圾回收时间不能超过1%
-XX:UseAdaptiveSizePolicy
   自适应GC模式,垃圾回收器将自动调整年轻代、老年代等参数,达到吞吐量、堆大小、停顿时间之间的平衡。
一般用于,手动调整参数比较困难的场景,让收集器自动进行调整。

Parallel Old

  Parallel 的老年版本,他们是jdk1.8默认的垃圾处理器。采用标记整理算法。支持并发。也是吞吐量优先。

cms

  cms只针对老年代,年轻代需要使用serial或者parNew配合。它是以响应时间优先。意图达到最短的停顿时间,
cms的标记过程分为以下几步
  1. 初始标记,简单的标记与gc roots直接关联的对象。需要stw
  2. 并发标记,从gcroot出发,开始并发标记存活的对象。不需要stw,与用户线程并发。
  3. 因为并发标记与用户并发,所以可能在标记阶段引用会发生变动,这个阶段就是处理并发标记过程中引用发生变动的对象,采用的是三色标记法解决的。
  4.并发清除,采用标记清除法,与用户线程一起运行
  因为清除阶段采用的是标记清除法,所以老年代的空间并不连续,当新的对象大小超过最大可分配空间大小时,会触发fullGc,使用serial回收器。
  又因为与用户线程一起运行,所以并发清除阶段会产生浮动垃圾,所以在垃圾回收时会预留空间,当预留空间不足以分配新对象时,会出现Concurrent Mode Failure,触发fullgc使用serial回收器。
  cms对于处理器资源比较敏感,cpu数小于4个时对用户影响较大。
  因为cms的问题比较多,所以没有任何一个版本使用cms为默认处理器

G1

  g1采用了分区法来分配内存。它默认将内存划分若干个大小相同的region,可以通过命令设置大小。每个region没有明确的身份划分,它们随着程序的运行改变身份,可以是Eden,Survivor,老年代。还有一个叫做Humongous的空间用来存储大对象,一般被当作老年代处理。在每个region里面,采用地址碰撞的方式存储数据。

  G1回收过程

  分为minorGc和混合Gc两部分,minor只处理Eden块中的垃圾。采用复制算法。需要stw。但是很短。混合Gc步骤如下:
  1. 初始标记,跟cms一样,初始标记也是只标记跟gc root直接关联的对象,这个过程可以在Minor GC过程中进行,所以基本不需要多余的消耗。
  G1的每个region都有一个叫做tams的东西,G1采用地址碰撞的方式分配空间,所以tams就存储了上次gc的位置和本次Gc的位置。在本次Gc位置之后的对象都视为存活,不参与本次回收。
  2. 并发标记,跟cms差不多,都是从gcROot开始可达性分析,标记存活对象,多线程并发并行的标记。与用户线程并行。
  3. satb,跟cms一样,会有漏标,采用三色标记和satb算法来解决漏标。需要短暂暂停
  4.多条线程并发并行清除,采用复制算法,因为涉及到对象的移动,所以需要暂停用户进程。

卡表和记忆集。

  jvm为了解决跨代调用的问题,引用了叫做记忆集的概念。卡表是记忆集的一种实现。
在进行minorGc时,如果一个老年代引用了年轻代,我们该怎么发现呢,扫描整个老年代的花销是很大的。在这时就用到了卡表,在分配新对象时如果老年代中的对象有引用这个对象的,就会在这个老年代对象对应的卡表的那一页标记为脏。进行minorGc时,只需要扫描标记为脏的卡页中的对象就行了。
  G1的记忆集实现有所不同,他在每个region中都维护了一个记忆集结构。它比较类似于map,假设A和B都是region,他们都被划分成了若干个区域。每个区域是一个卡页,A1,A2,A3。
A1和A3区域中有对象调用了regionB中的对象,那么在B的记忆集中就会出现这样的键值对。key是regionA的起始地址,value是A1和A3的索引,这样当b进行minorGC的时候只需要查询记忆集,找到regionA的位置,将A1A3卡页里面的对象加入到扫描中就可以了。

三色标记。

  在并发标记的时候,会将扫描过对象和他的子对象的标记为黑色,扫描了对象未扫描其子对象的标记为灰色,未扫描的对象标记为白色,扫描完成,仍为白色的就是垃圾对象。
漏洞:现有ABC三个对象,在扫描A对象时,A没有调用C,B调用的C,因为没有扫描B,所以C是白色,因为三色标记跟用户线程并行,A对像扫描完成后,调用了C,B对象解除调用,然后垃圾处理器开始扫描B对象,扫描完成后,此时C还是白色,因为A的扫描已经完成,无法再扫描新调用的c,b的扫描开始的时候已经不再调用c

  cms的解决方案是A对象的引用发生变化时将A置为灰色,让处理器重新扫描A,这样就可以发现c。
G1的解决方案是将C对象类似于gcroot在最终扫描阶段直接进行扫描。但是如果A没有引用C,C就是一个垃圾对象的话,在本次GC就无法清除,c就成为了一个浮动垃圾。只能下次清除。

安全区域和安全点

  为了保证stw不使程序出错,java设置了一系列指令作为安全点,比如方法调用循环跳转,异常跳转。jvm定义了一个中断标志,在需要stw时,线程并不会直接停止。线程会经常轮询这个标志,一旦发现标志为true,他就会到最近的安全点挂起。
  有的线程没有在执行状态,比如sleep,就没有办法到达安全点。所以jvm定义了安全区域
安全区域是指能够确保在某一段代码片段之中, 引用关系不会发生变化,这样在安全区域的任意一端都可以执行回收,线程在进入安全区域时,会标识自己进入了安全区域,jvm可放心进行垃圾回收,在快要出安全区域的时候,会不断轮询jvm,是否可以出。如果可以则继续执行,如果不行,就需要继续等待。直到回收完毕。

以下内容转自: 小明老师
G1 常用参数
-XX:+UseG1GC 启用 CMS 垃圾收集器
-XX:MaxGCPauseMillis 设置最大 GC 暂停时间的目标(以毫秒为单位)。这是一个软目标,并且 JVM 将尽最大的努力(G1 会尝试调整 Young 区的块数来)来实
现它。默认情况下,没有最大暂停时间值。
-XX:GCPauseIntervalMillis GC 的间隔时间
-XX:+G1HeapRegionSize 分区大小,建议逐渐增大该值,1 2 4 8 16 32。随着 size 增加,垃圾的存活时间更长,GC 间隔更长,但每次 GC 的时间也会更长
-XX:G1NewSizePercent 新生代最小比例,默认为 5%
-XX:G1MaxNewSizePercent 新生代最大比例,默认为 60%
-XX:GCTimeRatioGC 时间建议比例,G1 会根据这个值调整堆空间
-XX:ConcGCThreads 线程数量
-XX:InitiatingHeapOccupancyPercent 启动 G1 的堆空间占用比例,根据整个堆的占用而触发并发 GC 周期

几种常见的垃圾回收器相关推荐

  1. 几种常见的垃圾回收器和垃圾回收算法

    目录 常用版本默认垃圾回收器 1. Serial 收集器(串行收集器) 2. Serial Old 收集器 3. ParNew 收集器 4. Parallel scavenge 收集器(吞吐量优先收集 ...

  2. JVM从入门到精通(六):JVM调优必备理论知识 - 3种垃圾清除算法,常见的垃圾回收器

    JVM调优是一层窗户纸,只是看起来很难.学完本节课,让你: 熟悉 GC 常用算法,熟悉常见垃圾回收器,具有实际 JVM 调优实战经验 What is garbage 什么是垃圾?没有引用指向的对象就是 ...

  3. java8堆内存模型_「GC系列」JVM堆内存分代模型及常见的垃圾回收器

    1. 内存分代模型 为什么要说JVM的内存分代模型呢,因为内存分代和垃圾回收器的运行是有关系的. 现在大部分用到的垃圾回收器在逻辑上是分代的,除了G1之外的其他垃圾回收器在逻辑上和物理上都是分代的. ...

  4. 十种常见的垃圾回收器简介

    十种常见的垃圾回收器:Serial.SerialOld.ParallelScavenger.ParallelOld.ParNew.CMS.G1.ZGC.Shenandoah.Epsilon. Seri ...

  5. JAVA 四种引用类型和垃圾回收器

    JAVA 四种引用类型 强引用 在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用.当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的 ...

  6. 常见的垃圾回收器及垃圾回收算法

    我们知道,java为了让程序员更专注于代码的实现,而不用过多的考虑内存释放的问题,采用了自动的垃圾回收机制,也就是我们熟悉的GC. 有了垃圾回收机制后,程序员只需要关心内存的申请即可,内存的释放由系统 ...

  7. JVM常见的垃圾回收器

    一.常见垃圾收集器 现在常见的垃圾收集器有如下几种: 新生代收集器: Serial ParNew Parallel Scavenge 老年代收集器: Serial Old CMS Parallel O ...

  8. JVM的清洁工具——常见的垃圾回收器

    新生代和老年代垃圾回收算法不同的原因 在新生代中.每次垃圾回收都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活的对象的复制成本就可以完成回收.而老年代中因为对象存活率高,没有额 ...

  9. 常见的垃圾回收器算法有哪些,各有什么优劣?

    标记清除 这种算法分两分: 标记.清除两个阶段, 标记阶段是从根集合(GC Root)开始扫描,每到达一个对象就会标记该对象为存活状态,清除阶段在扫描完成之后将没有标记的对象给清除掉. 这个算法有个缺 ...

最新文章

  1. C++ 常用函数方法
  2. 脑电分析系列 | MNE-Python汇总
  3. java Socket Tcp 浏览器和服务器(一)
  4. 如何使用 Istio 进行多集群部署管理(一)
  5. [ZJOI2011]营救皮卡丘(费用流 + 最短路)
  6. sql server charindex函数和patindex函数详解(转)
  7. C++之继承探究(七):虚析构函数
  8. JavaScript面向对象那些事
  9. 超级简单的Android Studio jni 实现(无需命令行)
  10. Android 数字动画
  11. 机器学习笔记(参考吴恩达机器学习视频笔记)16_决策树
  12. AntPathMatcher路径匹配器,Ant风格的URL
  13. D3D中设备丢失的处理
  14. JAVA面试常考系列七
  15. java 某年某月的天数_Java练习 SDUT-1160_某年某月的天数
  16. 未找到beta版怎么解决_你要的直播解决方案来了!无需采集卡!
  17. ios无痕埋点_无痕埋点方案探究
  18. 母版页的详细使用介绍
  19. Cisco Packet Tracer 多区域OSPF配置实验
  20. 转贴:ubuntu 7.10 常用软件与编程环境搭建

热门文章

  1. (已解决)使火狐浏览器默认在新版标签页打开链接
  2. Windows11不显示WiFi图标
  3. 乡村少年宫计算机小组活动教案,少年宫计算机组教案定稿版.docx
  4. EJB_开发EJB容器模型的WEB服务
  5. 关于如何选择一家正规的PMP培训机构?
  6. R12 AR INVOICE 接口表导入
  7. Android 头像、图片裁剪
  8. puuty链接linux时间超时,Putty连接Linux提示timed out的解决办法
  9. minecraft服务器搭建教程_MC原版服务器搭建教程
  10. 中南大学计算机学硕毕业要求,中南大学研究生在学期间发表学术论文规定