什么是Java垃圾回收器

Java垃圾回收器是Java虚拟机(JVM)的三个重要模块(另外两个是解释器和多线程机制)之一,为应用程序提供内存的自动分配(Memory Allocation)、自动回收(Garbage Collect)功能,这两个操作都发生在Java堆上(一段内存快)。某一个时点,一个对象如果有一个以上的引用(Rreference)指向它,那么该对象就为活着的(Live),否则死亡(Dead),视为垃圾,可被垃圾回收器回收再利用。垃圾回收操作需要消耗CPU、线程、时间等资源,所以容易理解的是垃圾回收操作不是实时的发生(对象死亡马上释放),当内存消耗完或者是达到某一个指标(Threshold,使用内存占总内存的比列,比如0.75)时,触发垃圾回收操作。有一个对象死亡的例外,java.lang.Thread类型的对象即使没有引用,只要线程还在运行,就不会被回收。

回收的机制

依据统计分析可知,Java(包括一些其它高级语言)里面大多数对象生命周期都是短暂的,所以把Java内存分代管理。分代的目的无非就是为不同代的内存块运用不同的管理策略(算法),从而最大化性能。相对于年老代,通常年轻代要小很多,回收的频率高,速度快。年老代则回收频率低,耗时长。内存在年轻代里面分配,年轻代里面的对象经过多个回收周期依然存活的会自动晋升到年老代。

设计选型(Design Choices)

设计选型影响JVM垃圾回收器的实现难度,以及JVM的性能指标,适用于不同的场景。描述的是回收算法的风格特点。

单线程串行回收 VS 多线程并行回收

回收操作自身是否多线程处理的问题。单线程回收的优点是简单,易实现,碎片少,适用于单核的机器。多线程并行回收在多核机器上面可以充分的利用CPU资源,减少回收的时间,增加生产力,缺点是复杂且可能有部分碎片没有回收。

回收时暂停应用线程 VS 回收和应用并发进行

回收操作时是否暂停应用线程的问题。暂停应用线程的优点是简单、准确、清理得比较干净、清理的时间也短(CPU资源独占),缺点是暂停应用线程之后会造成垃圾回收周期内应用的回应时间拉长,实时性非常高的系统比较敏感。回收和应用线程并行处理的优点是应用反应时间比较平稳、缺点是实现难度大、清理频率高、可能有碎片。

不合并释放的内存片段 VS 合并释放的内存片段 VS 把活着的复制到新的地方

这三个选型描述的是如何管理死亡的内存块片段。死亡的内存片段通常散落在堆的各个地方,如果不加以管理会有两个问题,内存分配的时候因查找可用的内存而导致速度慢,小的碎片会导致内存的浪费(比如大的数组要求大的连续内存片段)。管理有两种方式,把活着的内存挪到内存块的某一端,记录可用内存的开始位置,或者干脆把活着的内存复制到一个新的内存区域,原来的内存块整个空出来。

性能指标(Performance Metrics)

①、生产率(Throughput)

一个较长的周期(长的周期才有意义)内,非回收时间占总时间的比率。度量系统的运行效率。

②、垃圾回收花费(Garbage Collection overhead)

一个较长的周期内,回收时间占总时间的比率。与生产率相对应,加起来为100%。

③、暂停时间间隔(Pause time)

Java虚拟机在回收垃圾的时候,有的算法会暂停所有应用线程的执行,某些系统可能对暂停的时间间隔比较敏感。

④、回收的频率(Frequency of collection)

平均多久会发生回收操作。

⑤、内存占用的大小(Footprint)

如堆的大小。

⑥、实时性(Promptness)

自一个对象死亡起,经过多久该对象所占用内存被回收。

垃圾回收的类型

所有的回收器类型都是基于分代技术。Java HotSpot虚拟机包含三代,年轻代(Young Generation)、年老代(Old Generation)、永久代(Permanent Generation)。

①永久代

存储类、方法以及它们的描述信息。可以通过-XX:PermSize=64m和-XX:MaxPermSize=128m两个可选项指定初始大小和最大值。通常 我们不需要调节该参数,默认的永久代大小足够了,不过如果加载的类非常多,不够用了,调节最大值即可。

②年老代

主要存储年轻代中经过多个回收周期仍然存活从而升级的对象,当然对于一些大的内存分配,可能也直接分配到永久代(一个极端的例子是年轻代根本就存不下)。

③年轻代

绝大多数的内存分配回收动作都发生在年轻代。如下图所示, 年轻代被划分为三个区域,原始区(Eden)和两个小的存活区(Survivor),两个存活区按功能分为From和To。绝大多数的对象都在原始区分配,超过一个垃圾回收操作仍然存活的对象放到存活区。

串行回收器(Serial Collector)

单线程执行回收操作,回收期间暂停所有应用线程的执行,client模式下的默认回收器,通过-XX:+UseSerialGC命令行可选项强制指定。

①年轻代的回收算法(Minor Collection)

把Eden区的存活对象移到To区,To区装不下直接移到年老代,把From区的移到To区,To区装不下直接移到年老代,From区里面年龄很大的升级到年老代。 回收结束之后,Eden和From区都为空,此时把From和To的功能互换,From变To,To变From,每一轮回收之前To都是空的。设计的选型为复制。

②年老代的回收算法(Full Collection)

年老代的回收分为三个步骤,标记(Mark)、清除(Sweep)、合并(Compact)。标记阶段把所有存活的对象标记出来,清除阶段释放所有死亡的对象,合并阶段 把所有活着的对象合并到年老代的前部分,把空闲的片段都留到后面。设计的选型为合并,减少内存的碎片。

并行回收器(Parallel Collector)

使用多个线程同时进行垃圾回收,多核环境里面可以充分的利用CPU资源,减少回收时间,增加JVM生产率,Server模式下的默认回收器。与串行回收器相同,回收期间暂停所有应用线程的执行。通过-XX:+UseParallelGC命令行可选项强制指定。

①年轻代的回收算法(Minor Collection)

使用多个线程回收垃圾,每一个线程的算法与串行回收器相同。

②年老代的回收算法(Full Collection)

年老代依然是单线程的,与串行回收器相同。

并行合并收集器(Parallel Compacting Collection)

年轻代和年老代的回收都是用多线程处理。通过命令可选项-XX:+UseParallelOldGC指定,–XX:ParallelGCThreads=3还可进一步指定参与并行回收的线程数。与串行回收器相同,回收期间暂停所有应用线程的执行。与并行回收器相比,年老代的回收时间更短,从而减少了暂停时间间隔(Pause time)。通过–XX:+UseParallelOldGC命令行可选项强制指定。

①年轻代的回收算法(Minor Collection)

与并行回收器(Parallel Collector)相同

②年老代的回收算法(Full Collection)

年老代分为三个步骤,标记、统计、合并。这里用到分的思想,把年老代划分为很多个固定大小的区(region)。 标记阶段,把所有存活的对象划分为N组(应该与回收线程数相同),每一个线程独立的负责自己那一组,标记存活对象的位置以及 所在区(Region)的存活率信息,标记为并行的。统计阶段,统计每一个区(Region)的存活率,原则上靠前面的存活率较高,从前到后, 找到值得合并的开始位置(绝大多数对象都存活的区不值得合并),统计阶段是串行的(单线程)。合并阶段,依据统计阶段的信息,多线程 并行的把存活的对象从一个区(Region)复制到另外一个区(Region)。

并发标记清除回收器(Concurrent Mark-Sweep Collector)

又名低延时收集器(Low-latency Collector),通过各种手段使得应用程序被挂起的时间最短。基本与应用程序并发地执行回收操作,没有合并和复制操作。通过命令行-XX:+UseConcMarkSweepGC指定,在单核或者双核系统里面还可以指定使用增量式回收模式-XX:+UseConcMarkSweepGC。增量式回收是指把回收操作分为多个片段,执行一个片段之后释放CPU资源给应用程序,未来的某个时点接着上次的结果继续回收下去。目的也是减少延时。

①年轻代的回收算法(Minor Collection)

与并行回收器(Parallel Collector)相同

②年老代的回收算法(Full Collection)

分为四个步骤,初始标记(Initial Mark)、并发标记(Concurrent Mark)、再次标记(Remark)、以及并发清理(Concurrent Sweep)。特别注意,没有合并操作,所以会有碎片。

初始化阶段: 暂停应用线程,找出所有存活的对象,耗时比较短,回收器使用单线程。

并发标记阶段: 回收器标记操作与应用并发运行,回收器使用单线程标记存活对象。

再次标记:并发标记阶段由于应用程序也在运行,这个过程中可能新增或者修改对象。所以再次暂停应用线程,找出所有修改的对象,使用多线程标记。

并发清理:回收器清理操作与应用并发运行,回收器使用单线程清理死亡对象。

Java垃圾回收器的性能评估工具

①–XX:+PrintGCDetails和–XX:+PrintGCTimeStamps

垃圾回收的开始时间,持续时间,每一代的空余内存等信息。

②jmap [options] pid

jamp 2043 查看2043进程里面已经加载的共享对象。通常DLL文件。

jmap -heap 2043 查看内存堆的配置信息以及使用情况。

jmap -permstat 2043 查看永久代的加载情况。

jmap -histo 2043 查看类的加载和内存占用情况。

③jstat [options] pid

jstat -class 2043 class加载、卸载、内存占用情况。

jstat -gc 2043 GC执行情况。

后记

Java提供自动选择和自动性能优化功能。在做垃圾回收器调优之前,先列出所关注的性能指标,通过命令行告诉JVM你所关注的性能指标,由JVM自动调优,如果不满意,可以指定垃圾回收器。OutOfMemory通常是由于堆内存不足,调节-Xmx1024m和-XX:MaxPermSize=128m命令行可选项即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

java垃圾回收的优点和原理_Java垃圾回收器的方法和原理总结相关推荐

  1. 【Java面试题】49 垃圾回收的优点和原理。并考虑2种回收机制。

    1.Java语言最显著的特点就是引入了垃圾回收机制,它使java程序员在编写程序时不再考虑内存管理的问题.  2.由于有这个垃圾回收机制,java中的对象不再有"作用域"的概念,只 ...

  2. 请说明一下垃圾回收的优点以及原理

    ● 请说明一下垃圾回收的优点以及原理. 考察点:垃圾回收 参考回答: Java 语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序 ...

  3. java垃圾回收(一)——什么是垃圾

    最近主要时间都放在知识图谱构建中,但是还是需要给自己充电.想在近段时间好好把 JVM 的垃圾回收好好看一下,学习然后输出,是我新找到的有效学习方法,希望你看了之后能有收获. 什么是垃圾 垃圾回收(常称 ...

  4. jvm学习第十、十一天、十二天—垃圾回收器1、垃圾回收的相关概述2、 垃圾回收相关算法3、 垃圾回收器

    标题:jvm学习第十.十一天.十二天-垃圾回收器 学习内容: 1.垃圾回收的相关概述 2. 垃圾回收相关算法 3. 垃圾回收器 内容详情: 1.垃圾回收的相关概述 什么是垃圾( Garbage)? 垃 ...

  5. 简介三种垃圾回收机制:分代复制垃圾回收,标记垃圾回收,增量垃圾回收

    一.分代复制垃圾回收 不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象,其中有些对象是与业务信息相关,比 ...

  6. 解读.net垃圾回收和CLR 4.0对垃圾回收所做的改进之一-.Net编程教程

    解读.net垃圾回收和CLR 4.0对垃圾回收所做的改进之一-.Net编程教程 来源:模板无忧 作者:编辑整理更新时间:2009-07-19点击:114 A survey of garbage col ...

  7. JavaScript基础09-day11【原型对象、toString()、垃圾回收、数组、数组字面量、数组方法】

    学习地址: 谷粒学院--尚硅谷 哔哩哔哩网站--尚硅谷最新版JavaScript基础全套教程完整版(140集实战教学,JS从入门到精通) JavaScript基础.高级学习笔记汇总表[尚硅谷最新版Ja ...

  8. java 终结此段代码并重新运行_Java垃圾回收

    好久没看关于java的书了, 最近, 看了James Gosling的<>, 做了一些读书笔记. 这部分是关于垃圾回收的. 1.垃圾回收 对象是使用new创建的, 但是并没有与之相对应的d ...

  9. Java垃圾回收(GC)、找垃圾的方式、GC Root、GC停顿、引用、垃圾收集算法、收集器、GC日志、安全点、安全区域

    1.垃圾回收 1.1概念 在Java语言中,垃圾回收(Garbage Collection,GC)是一个非常重要的概念. 它的主要作用是回收程序中不再被使用的内存,Java提供的GC功能可以自动监测对 ...

  10. java list原理_Java集合:ArrayList的实现原理

    目录: 一. ArrayList概述: ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单 ...

最新文章

  1. WINDOWS2003域控制器禁止U盘
  2. Ardino基础教程 17_四位数码管
  3. C++11线程管理基础
  4. windows git 更改为unix模式换行符决解方法
  5. 补发《超级迷宫》站立会议三
  6. bootstrap 居中 表格中_使用Twitter Bootstrap在表格单元格中垂直居中
  7. PHP 二分查找(详细)
  8. 安全云服务的定义和特征
  9. Atitti  css   transition Animation differ区别
  10. html让font居中,用CSS做将如何字体居中?
  11. MS17010漏洞利用姿势
  12. 认知水平高下定义及提高认知水平的方法
  13. 飞秋下载 官方唯一的下载地址
  14. VF控制和矢量控制的一些区别
  15. SX1262 与 SX1278、SX1276 有什么区别?
  16. 招行汇钱到华美银行(1)
  17. 为什么OpenCV4 “pkg-config --modversion opencv”显示“ No package ‘opencv‘ found”?解决方法!
  18. 2022.1.17学习总结
  19. android 自定义铃声 代码,Android通过代码设置铃声
  20. 次要和主要等位基因的定义

热门文章

  1. MySQL的锁到底有多少内容?和腾讯大佬的技术面谈,我真菜
  2. MFS(一)---mfs详解与部署
  3. hao123劫持浏览器主页
  4. android界面自动跳转,android实现欢迎界面的自动跳转
  5. POJ 1581 A Contesting Decision
  6. 360修复高危漏洞可以修复吗_Win7系统360安全卫士提示“进行漏洞的修复”是否该修复?...
  7. iis+php解析漏洞修复,IIS+PHP fastcgi模式 pathinfo取值错误任意代码执行漏洞修复方法...
  8. 淘宝客是鸡肋还是熊掌
  9. H.266/VVC代码学习:普通量化和率失真优化量化(RDOQ)
  10. Ubuntu下装codeblocks