前言:如果说收集算法是内存回收的方法论,那么垃圾收集器则是内存回收的实践者。整哥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虚拟机(JVM):第四幕:自动内存管理 - 经典垃圾收集器的更多相关文章

  1. 深入理解Java虚拟机之读书笔记一 自动内存管理机制

    一.运行时数据区域 1.程序计数器是线程的私有空间,每个线程都有.针对线程执行的是Java代码还是Native代码有两种取值,Java代码时:虚拟机字节码指令的地址:Native代码时:计数值为Und ...

  2. JAVA之自动内存管理机制

    一.内存分配 1.JVM体系结构 2.运行时数据区域 3.内存分配二.内存回收 1.垃圾收集算法 2.垃圾收集器三.相关参考一.内存分配JVM体系结构 在了解自动内存管理的内存分配之前,我们先看下JV ...

  3. .NET 自动内存管理(垃圾收集GC)

    自动内存管理(垃圾收集GC) 在面向对象的环境里, 要使用资源,必须为响应 的类型分配一定 的内存空间.下面是访问一个资源所需要的几个步骤: 1. 调用中间语言(IL)的newobj 指令.当我们用N ...

  4. JVM | 第1部分:自动内存管理与性能调优《深入理解 Java 虚拟机》

    目录 前言 1. 自动内存管理 1.1 JVM运行时数据区 1.2 Java 内存结构 1.3 HotSpot 虚拟机创建对象 1.4 HotSpot 虚拟机的对象内存布局 1.5 访问对象 2. 垃 ...

  5. [深入理解Java虚拟机]<自动内存管理>

    Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就 ...

  6. 深入理解Java虚拟机(自动内存管理机制)

    文章首发于公众号:BaronTalk 书籍真的是常读常新,古人说「书读百遍其义自见」还是很有道理的.周志明老师的这本<深入理解 Java 虚拟机>我细读了不下三遍,每一次阅读都有新的收获, ...

  7. JVM自动内存管理-Java内存区域与内存溢出异常

    摘要: JVM内存的划分,导致内存溢出异常的可能区域. 1. JVM运行时内存区域 JVM在执行Java程序的过程中会把它所管理的内存划分为以下几个区域: 1.1 程序计数器 程序计数器是一块较小的内 ...

  8. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

  9. JVM自动内存管理机制——Java内存区域(上)

    一.JVM运行时数据区域概述 Java相比较于C/C++的一个特点就是,在虚拟机自动内存管理机制的帮助下,我们不需要为每一个操作都写像C/C++一样的delete/free代码,所以也不容易出现内存泄 ...

  10. 【深入理解Java虚拟机】自动内存管理机制——垃圾回收机制

      Java与C++之间有一堵有内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来.C/C++程序员既拥有每一个对象的所有权,同时也担负着每一个对象生 ...

随机推荐

  1. -Xmx参数建议设置为系统内存的多少?

    在设置 -Xmx 参数时,建议将其设置为系统内存的一定比例.具体的比例需要根据应用程序的特点.系统资源的限制等各种因素进行综合考虑. 如果将 -Xmx 参数设置得过小,可能会导致 JVM 分配的堆内存 ...

  2. 【C#/.NET】MAUI上的依赖注入

    ​ 引言 在移动应用开发中,依赖注入是一项非常重要的技术,它可以帮助我们简化代码结构.提高可维护性并增加测试覆盖率.在最新的.NET跨平台框架MAUI中,我们也可以利用依赖注入来构建高效的应用程序架构 ...

  3. FFmpeg+SDL实时解码和渲染H264视频流

    前言 之前实现了Android手机摄像头数据的TCP实时传输,今天接着聊聊,如何在PC端把接收到的H264视频流实时解码并渲染出来.这次使用的语言是C++,框架有FFmpeg和SDL2. 解码 解码部 ...

  4. T-star高校挑战赛部分wp

    web-1签到 checkin还是很基础的 网站上传存在js检测,禁用js即可上传 写PHP一句话木马上传,http://588f25a5.yunyansec.com/upload/test.php连 ...

  5. Git插件报错,Appears to be a git repo or submodule

    Hexo博客需要引入第三方插件,不少包作者误把包项目得.git文件上传到github,或者在插件的github路径下直接下载插件文件夹,结果是插件内含有.git文件,导致下载别的npm包时报错npm ...

  6. 用字符串表达式执行引擎消除掉if else if

    背景 最近我搞了个微信机器人,@机器人 xxx 这样来发送命令 能拿到的信息有,消息内容,消息发送人,消息所在的群id等 需要根据消息内容或者消息发送群id等不同的条件组合来决定走哪个处理逻辑. 简单 ...

  7. git 访问仓库错误

    通过https访问git出现错误, failed: Error in the pull function 尝试将https改为http

  8. Redis和Mysql保持数据一致性

    1.简述   在高并发的场景下,大量的请求直接访问Mysql很容易造成性能问题.所以,我们都会用Redis来做数据的缓存,削减对数据库的请求.但是,Mysql和Redis是两种不同的数据库,如何保证不 ...

  9. loopback4:单元测试冻结时间

    解决方案 import {expect} from '@loopback/testlab'; import sinon from 'sinon'; describe('example test', ( ...

  10. Docker数据持久化与数据共享

    上篇文章的最后我们使用Docker部署了一个纯前端项目,但还有一个很重要的问题就是容器中产生的数据(比如log文件),容器一旦被删除,容器内的所有数据也就没有了,为了避免这个问题我们可以将数据存储到容 ...