首页 > 系统相关 >Java虚拟机(JVM):第四幕:自动内存管理 - 经典垃圾收集器

Java虚拟机(JVM):第四幕:自动内存管理 - 经典垃圾收集器

时间:2023-07-09 21:24:30浏览次数:50  
标签:Java G1 收集器 虚拟机 线程 垃圾 CMS Region

  前言:如果说收集算法是内存回收的方法论,那么垃圾收集器则是内存回收的实践者。整哥Java堆 :Full GC。

  1、Serial收集器:最基础、历史最悠久的收集器,这是一个单线程工作的收集器。

  2、ParNew收集器:是Serial收集器的多线程并行版本,可以说是跟Serial完全一样。

  CMS收集器:实现了垃圾收集线程与用户线程(基本上)同时工作,作为老年代的收集器,ParNew收集器是激活CMS后的默认新生代的收集器,直到CMS的出现巩固了PartNew收集器的位置。然后,PartNew合并入CMS中,成为它专门处理新生代的组成部分,存在线程交互的开销。

  3、Parallel Scavenge 收集器:是一款新生代收集器,基于标记 - 复制算法实现的收集器,也是并行收集的多线程收集器。特点主要是与其他收集器不同,CMS收集器的关注点尽可能地缩短垃圾收集时的用户线程的停顿时间。而Parallel Scavenge 收集器的目标是达到一个可控制的吞吐量

  所谓吞吐量是处理器用于运行用户代码的时间与处理器 总消耗时间的比值:

  停顿时间越短越需要与用户交互且需要保证服务响应质量的程序,Parallel Scavenge 收集器提供了两个参数来精确的控制吞吐量:分别为控制最大垃圾收集停顿时间的参数以及直接设置吞吐量大小的参数。Parallel Scavenge 收集器也被称为“吞吐量优先收集器”。除了上述的两个参数之外,还有一个开关参数,这种调节方式被称为垃圾收集的自适应调整策略。自适应调整策略也是Parallel Scavenge 收集器区别于ParNew收集器的一个重要特征。

  4、Serial Old 收集器:是Serial收集器的老年代版本,同样是一个单线程收集器,使用标记 - 整理算法。主要是供客户端模式下的HotSpot虚拟机使用。

  5、Parallel Old 收集器:同样是Parallel Scavenge 收集器的老年代版本,支持多线程并发收集,基于标记 - 整理算法来实现,与Parallel Scavenge 收集器的搭配,满足了“吞吐量优先”的收集器

  6、CMS收集器:是一种基于标记 - 清除的算法来实现的,主要用来获取最短回收停顿时间为目标的收集器,较为关注服务的响应速度,希望系统的停顿时间尽可能的短,来给用户带来良好的交互体验。运行过程主要有四个步骤,包括:1、初始标记。2、并发标记。3、重新标记。4、并发清除。

  CMS收集器有很明显的缺陷。首先CMS收集器对于处理器资源非常的敏感,只有在核心的处理器数量在四个或以上时,回收垃圾的线程才不会占用太多的处理器资源,因此面对这种情况,提供了一种增量式并发收集器,用户线程交替运行,尽可能减少垃圾收集线程的独占时间,虽然会导致整个垃圾的手机过程变长,但是对于用户程序的影响会显得小一些。

  浮动垃圾:在CMS的并发标记和并发清理阶段,用户线程是继续运行的,程序在运行时伴随着新的垃圾对象不断产生,但是这一部分垃圾对象时出现在标记过程之后,CMS收集器没有办法在本次处理掉它们,只好留待下一次垃圾收集时,再次清理掉。

  7、Garbage First收集器:简称为G1收集器:局部收集的设计思路,在JDK 10的时候,提出使用“统一的垃圾收集器接口”,将内存回收的“行为”与“实现”进行分离。用来关注停顿时间的控制来进行收集垃圾。G1收集器开创了基于Region的堆内存布局,将连续的Java堆划分为多个大小相等的独立区域,根据需求去扮演新生代的不同空间。

  此外,Region还有一类特殊的Humongous区域,用来存储大对象:超过一个Region区域一半容量的对象。虽然G1收集器保留了新生代与老年代的概念。这是因为,G1收集器建立了可预测的停顿时间模型。

  Region作为单次回收的最小单元,思路:跟踪每一个Region里面的垃圾积累的“价值”大小,价值:回收所获得的空间大小以及回收所需要时间的经验值,后台建立维护一个优先级的列表,来优先回收处理收益最大的Region。

  针对Java堆分为多个独立的Region,Region之间存在的跨Region引用对象,采用卡表(我指向谁,谁指向我)的形式,G1收集器通过原始快照(SATB)算法来保证收集线程与用户线程互不干扰地运行。为了持续的创建新的对象,G1为每一个Region设计了两个名为TAMS的指针,将一部分空间划分出来用于并发回收过程中的新对象分配,默认在这个地址上的对象是被隐式标记的,默认为存活状态。

  每一种垃圾收集器都有自己的优点和缺点,针对具体的场景,需要具体的分析。随着时间的发展,HotSpot虚拟机的开发者对于G1的不断优化,让G1在收集器的占有率市场一直稳步提高。

标签:Java,G1,收集器,虚拟机,线程,垃圾,CMS,Region
From: https://www.cnblogs.com/kuangmeng/p/17534648.html

相关文章

  • 开心档之Java 测验
    目录Java测验 Java测验Java测验技术文档Java测验是一种衡量Java编程水平的测试,可以通过一系列问题和编程任务来测试Java开发人员的技能水平和理解程度。Java测验可以用于聘用程序员、衡量编程实践水平和掌握Java的程度。Java测验通常涵盖以下主题:基本语法-测试Ja......
  • Java - JavaWeb - Concepts
    1.Servlet配置1.1.配置父级项目配置好IntellijIDEA/MAVEN之后, 创建一个新项目com.crevew.javaweb-02-servlet,然后删除所有的SRC(方便接下来创建servlet模块);然后更新最外面的父pom.xml,加上<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.......
  • String内存模型和Java常用方法
    一、String内存模型1、直接赋值创建string对象内存原理:StringTable(串池):字符串常量池,用来存储字符串,只能是在直接赋值中使用才会存在串池当中(JDK7前串池是在方法区里面,StringTable(串池)在JDK7版本开始从方法区中挪到了堆内存,但是运行机制没有发生变化)eg:首先mian方法进栈,创建变......
  • 面试类-Java基础 (三)
    String是Java基本数据类型吗?可以被继承吗?String是Java基本数据类型吗?不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitivetype),剩下的都是引用类型(referencetype)。String是一个比较特殊的引用数据类型......
  • JVM垃圾收集器(三) ------ 垃圾回收器(一)
    垃圾回收器分类按照线程数分• 串行垃圾回收器• 同一段时间内只允许一个CPU执行垃圾回收的操作,此时工作线程暂停,直至垃圾收集工作结束• 单CPU或者较小的应有等内存硬件平台不是特别优越的场合,串行回收器的表现就可以超过所并行回收器和并发回收器• 串行回收器默认应有在客......
  • 【java】虚拟机的内存划分
    为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。  区域名称作用程序计数器程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址本地方法栈当程序中调用了native的本地方法时,本地方法执行......
  • 【java】输入输出
    输出换行输出语句:输出内容后进行换行,格式如下:System.out.println(输出内容);//输出内容之后,紧接着换行不换行输出语句:输出内容后不换行,格式如下System.out.print(输出内容);////输出内容之后不换行 示例代码:publicclassTestPrintlnAndPrint{publicstaticvoid......
  • 【java】数据类型
    Java的数据类型分为两大类:基本数据类型:包括整数、浮点数、字符、布尔。引用数据类型:包括数组、类、接口、枚举、注解。   自动类型转换(1)当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围大的变量时。inti='A';//char自动升级为int,其......
  • java日志框架
    发展简图历程:使用logback+slf4j进行日志框架处理,出自一人之手,衔接更好! logback官网手册(英文):https://logback.qos.ch/manual/index.htmllogback中文手册:http://www.logback.cn/博客中文手册:https://blog.csdn.net/qq_26462567/article/details/115757354 ......
  • 【java】源文件和类
    (1)源文件名是否必须与类名一致?public呢?如果这个类不是public,那么源文件名可以和类名不一致。但是不便于代码维护。如果这个类是public,那么要求源文件名必须与类名一致。否则编译报错。我们建议大家,不管是否是public,都与源文件名保持一致,而且一个源文件尽量只写一个类,目的是为......