JAVA垃圾回收Garbage Collection(二、垃圾收集器

垃圾收集器

  • HotSpot虚拟机的垃圾收集器

    •   Java虚拟机规范中对垃圾收集器如何实现没有任何规定,因此不同版本的虚拟机所提供的垃圾收集器都可能有很大的差别,并且都会提供参数供用户自己应用的特点和要求组合出各个年代使用的收集器。java 1.7之后的Hotspot虚拟机包含的收集器如下:
    • 新生代收集器:Serial ,ParNew,Parallel Scavenge
    • 老年代收集器:CMS,Serial Old,Parallel Old
    • 独立堆收集器:G1
  • Serial收集器
    •   serial收集器是最基本发展历史最悠久的收集器。在jdk1.3之前是虚拟机新生代收集的唯一选择。这个收集器是单线程收集器,但它单线程的意义并不仅仅说明它只会使用一个CPU或者一条收集线程去完成垃圾收集工作,更重要的是,它进行垃圾收集时,必须暂停其他所有的线程,之道它收集结束。"Stop The World"是这个收集器的特点。这个工作其实是由虚拟机在后台自动发起自动完成的在用户不可见的情况下把用户正常工作的线程全部停掉对很多应用难以接受。但是虚拟机开发团队为消除或者工作线程因为内存回收而导致的停顿一直努力进行着,从serial到Parallel收集器到CMS再到G1,一个个越来越优秀的收集器出现,用户线程停顿时间不断缩短,但是仍然没办法消除。
    • serial优点:简单高效,对单CPU的环境Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率,在应用场景中分配给虚拟机内存的一般不会很大,收集几十上百兆的新生代时,停顿时间可以控制到几十毫秒最多一百毫秒内只要不是频繁发生这点停顿是可以接受的。所以serial在Client模式下的虚拟机是个很好的选择。
  • ParNew收集器
    •   ParNew收集器其实是Serial收集器的多线程版本,除了使用多线程进行垃圾回收外,其余包括Serial收集器的所有可控参数,收集算法,Stop The World 对象分配规则,回收策略都和Serial一样。示意图如下:
    • 目前只有ParNew收集器能和CMS收集器配合工作,成为Server模式下虚拟机的首选新生代收集器。
  • Parallel  Scavenge收集器
    •   新生代收集器,使用的也是复制算法Parallel Scavenge收集器的特点是它的关注点和其他收集器不同CMS等收集器的关注点是尽可能的缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控的吞吐量(ThroughPut)。吞吐量:就是cpu用于运行用户代码的时间与cpu总消耗时间的比值,吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),虚拟机运行了100分钟,垃圾收集花掉1分钟,吞吐量就是99%。

      • Parallel Scavenge 收集器总共有两个参数用以精确控制吞吐量分别是:最大垃圾收集停顿时间-XX:MaxGCPauseMills,直接设置吞吐量大小的-XX:GCTimeRatio
      • MaxGCPauseMills:GC停顿时间缩短是牺牲吞吐量和新生代空间换来的,系统把新生代调小点,收集200M肯定比500M快,这也导致垃圾收集器更加频繁的原来10s一次,每次100ms,现在是5s一次每次70ms。停顿时间下来了,吞吐 量也下来了。
      • GCTimeRatio:0-100的整数,垃圾收集时间占总时间的占比,就是吞吐量的倒数;如默认是99 就是占用1%(1/(99+1))的垃圾收集时间;
      • -XX:+UseAdaptiveSizePolicy:打开后不需要手动设定Eden Survivor比例,老年代对象大小的细节参数,续集及会动态调整这些参数以提供最适合的停顿时间或者最大的吞吐量。自适应调节也是与ParNew收集器的重要区别。
  • Serial Old
    •   serial的老年代版本,单线程收集器使用标记-整理算法,主要在Client模式下的虚拟机下使用
    •   JDK1.5之前与Parallel Scavenge收集器搭配使用,CMS的后备预案
  • Parallel Old
    •   Parallel Scavenge收集器的老年代版本,使用多线程和标记整理算法。
    • 新生代如果选择了Parallel Scavenge收集器,老年代只能使用Serial Old,有了Parallel Old出现后,在注重吞吐量和CPU敏感的资源场合可以优先使用Parallel Scavenge和Parallel Old组合。
  • CMS(Concurrent Mark Sweep)
    •   
  • G1(Garbage First)
    • G1收集器是一款面向服务端应用的垃圾收集器

      • 并行与并发:G1能充分利用多CPU多核环境下的硬件优势,使用多个CPU来缩短Stop-The-World的时间
      • 分代收集:G1收集器可收集新生代老年代两种,不需要其他收集器配合就可以独立管理整个GC堆
      • 空间整合:G1采用"标记-整理"算法实现收集器,意味着G1运作期间不会产生内存空间碎片,收集后可提供规整的可用内存
      • 可预测的停顿:建立可预测的停顿时间模型,能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集器上的时间不得超过N毫秒

原文地址:https://www.cnblogs.com/xilingnote/p/9386379.html

时间: 2024-08-03 23:38:57

JAVA垃圾回收Garbage Collection(二、垃圾收集器的相关文章

[Java] 垃圾回收 ( Garbage Collection ) 的步骤演示

关于 JVM 垃圾回收机制的基础内容,可参考上一篇博客 垃圾回收机制 ( Garbage Collection ) 简介 上一篇博客,介绍了堆的内存被分为三个部分:年轻代.老年代.永生代.这篇博文将演示这三个部分如何交互,实际也演示了垃圾回收. 1. 首先,所有新创建的对象都会陪分配到年轻代的 Eden 空间,而两个 survior 空间一开始都为空. 下图表示的是运行一段实际后的年轻代内存情况,新创建的对象会被放在 Eden 空间,"from" survior space 里面的数字

java垃圾回收Garbage Collection(一、垃圾收集算法)

垃圾收集算法 标记-清除算法 最基础的算法是标记-清除(Mark-Sweep)算法.分为标记和清除两个阶段:首先标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象.之所以说是最基础的收集算法,是因为后续的收集算法都是基于这种思路并对其不足进行改进而得到的.它主要有两个不足之处:一个是效率标记和清除效率都不高:另一个是空间问题标记清除后产生大量的不连续内存碎片,空间碎片过多可能会导致以后程序运行过程中需要分配较大的对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作.标记清除算

垃圾回收(garbage collection)介绍

 垃圾回收用来实现内存的自动管理(automatic management),区别于人工管理(manual management).人工管理内存容易出现的问题: 1)悬垂指针,dangling pointer 2)重复回收,Double free 3)内存泄露,memory leak 历史 垃圾回收的概念及技术由John McCarthy于1959年发明,应用于List语言中.1959年,计算机科学应该还处于探索.萌芽阶段,但这位大神已经发明了垃圾回收,大神就是大神. 策略 目前的垃圾回收策

JVM(十一),垃圾回收之老年代垃圾收集器

十一.垃圾回收之老年代垃圾收集器 1.Serial Old收集器(标记整理算法-单线程-Client模式下) 2.Paraller Old收集器(标记整理算法-多线程-) 3.CMS收集器(标记清除算法) 4.G1收集器(新生代,老年代都可以用) 原文地址:https://www.cnblogs.com/xzmxddx/p/10366914.html

垃圾回收算法和JVM垃圾收集器(一)

参考文献:深入理解Java虚拟机 周志明 Java编程思想 Bruce Eckel 为什么自动化垃圾回收后还要了解GC呢:当需要排查各种溢出.内存泄漏问题时,当垃圾收集成为系统达成更高并发量的瓶颈时,我们就需要对这些“自动化”的技术实施必要的监控和调节. 垃圾回收的主要区域:Java堆和方法区 那么,如何判断对象是否已经可以回收呢?主要有两种方法: 一.引用计数算法:每个对象都有一个引用计数器,当有引用连接至对象时,引用计数器加1:当引用计数器离开引用作用域被置null时,引用计数减1.垃圾回收

深入理解Java虚拟机之读书笔记二 垃圾收集器

1.对象已死? a.引用计数算法:缺点是它很难解决对象之间的相互循环引用的问题,Java语言中没有选用它. b.根搜索算法(GC Roots Tracing):通过一系列的名为"GC Roots"的对象作为起始点,开始向下搜索,走过的路径称为引用链,当一个对象没有任何引用链相连,表面此对象不可达.在Java语言中,可作为GC Roots的对象包括: 虚拟机栈(栈帧中的本地变量表)中的引用的对象. 方法区中的类静态属性引用的对象. 方法区中的常量引用的对象. 本地方法栈中JNI的引用的对

GC垃圾回收 | 深入理解G1垃圾收集器和GC日志

来源:并发编程网链接:http://ifeve.com/深入理解G1垃圾收集器/ G1 GC是Jdk7的新特性之一.Jdk7+版本都可以自主配置G1作为JVM GC选项:作为JVM GC算法的一次重大升级.DK7u后G1已相对稳定.且未来计划替代CMS.所以有必要深入了解下: 不同于其他的分代回收算法.G1将堆空间划分成了互相独立的区块.每块区域既有可能属于O区.也有可能是Y区,且每类区域空间可以是不连续的(对比CMS的O区和Y区都必须是连续的).这种将O区划分成多块的理念源于:当并发后台线程寻

终结 finalize()和垃圾回收(garbage collection)

1.为什么要有finalize()方法? 假定你的对象(并非使用new)获得了一块"特殊"的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以他不知道该如何释放该对象的这块"特殊"内存,为了应对这种情况,java 允许在类中定义一个finalize()的方法. protected void finalize(){ } 2.finalize()方法在何时调用? 一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次

Java垃圾回收机制

Java的内存分布 在JVM中,内存是按照分代进行组织的. 其中,堆内存分为年轻代和年老代,非堆内存主要是Permanent区域,主要用于存储一些类的元数据,常量池等信息.而年轻代又分为两种,一种是Eden区域,另外一种是两个大小对等的Survivor区域.之所以将Java内存按照分代进行组织,主要是基于这样一个"弱假设" - 大多数对象都在年轻时候死亡.同时,将内存按照分代进行组织,使得我们可以在不同的分代上使用不同的垃圾回收算法,使得整个内存的垃圾回收更加有效. 年轻代的垃圾回收