`

JAVA虚拟机-GC介绍和垃圾算法理解(二)

 
阅读更多

1.GC介绍

垃圾回收器(Garbage Collection,GC),顾名思义,垃圾回收就是释放垃圾占用的空间, Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理。

我们需要考虑一下JVM处理垃圾回收三个问题:

1).哪些内存需要回收?

2).GC什么时候开始回收?

3).如何回收

 

2.垃圾收集方式

2.1 引用计数

2.2 对象遍历引用

 

3.垃圾收集算法

垃圾收集算法主要有: Mark-sweepmark-compactcopying 三种.
1).复制copying:
找到活动对象拷贝到新的空间
适合存活对象较少情况,增加内存成本高 (使用于年轻代回收
2).标记清除
从跟开始将活动对象标记,然后再扫描未标记的一次回收
不需要移动对象,仅对不存活对象处理,适合存活对象较多情况,会造成内存碎片(适合老年代回收)

3).标记压缩

在标记清除基础上,往左移动存活对象

成本高,好处是没有碎片

 

4.三种基本算法简要对比: 

 



时间开销: 
mark-sweep:mark阶段与活对象的数量成正比,sweep阶段与整堆大小成正比 
mark-compact:mark阶段与活对象的数量成正比,compact阶段与活对象的大小成正比 
copying:与活对象大小成正比 

如果把mark、sweep、compact、copying这几种动作的耗时放在一起看,大致关系: 
compaction > copying > marking > sweeping 
还有 marking + sweeping > copying  
 
虽然compactiont与copying都涉及移动对象,但算法实现存在不同,
compact可能要先计算一次对象的目标地址,然后修正指针,然后再移动对象;
copying则可以把这几件事情合为一体来做,所以可以快一些。 

年轻代:
在分代式垃圾中,年轻代中的对象在minor GC时的存活率应该很低,这样用copying算法就是最合算的,因为其时间开销与活对象的大小成正比,如果没多少活对象,它就非常快;而且young gen本身应该比较小,就算需要2倍空间也只会浪费不太多的空间.那么影响新生代GC的主要因素排序:存活对象数 > 新生代大小 > 老年代算法
 
老年代:
分代式GC里,老年代CMS常用mark-sweep或者是mark-sweep + mark-compact的混合方式,一般情况是用mark-sweep,统计估算碎片量达到一定程度时用mark-compact。老年代被GC时对象存活率可能会很高,而且假定可用剩余空间不太多,这样copying算法就不太合适,于是有另两种算法:mark-sweep,mark-compact.
HotSpot VM中老年代除了CMS之外的其它收集器都是会移动对象的,也就是要么是copying、要么是mark-compact的变种。 
 
CMS为什么用mark-sweep基本算法将其并发化,而不使用移动对象的算法?(ps:原理出自淘宝沙迦) 
 
主要原因分析:GC之外的代码(应用代码)和 GC的代码(collector),两者之间需要保持同步,这样才可以保证两者所观察到的对象图是一致的。 
如果是一个串行、不并发、不分代、不增量式的collector,那么它在工作的时候总是能观察到整个对象图。因而它跟应用代码之间的同步方式非常简单:应用代码一侧不用做任何特殊的事情,只要在需要GC时同步调用collector即可。 

如果有一个分代式的,或者增量式的collector,那它在工作的时候就只会观察到整个对象图的一部分;它观察不到的部分就有可能与应用代码产生不一致,于是需要应用代码配合:它与应用代码之间需要额外的同步。应用代码在改变对象图中的引用关系时必须执行一些额外代码,让collector记录下这些变化。有两种做法,一种是write barrier,一种是read barrier。 

通常一个程序里对引用的读远比对引用的写要更频繁,所以通常认为read barrier的开销远大于write barrier,所以很少有GC使用read barrier。 
如果只用write barrier,那么“移动对象”这个动作就必须要完全暂停应用代码,让collector把对象都移动好,然后把指针都修正好,接下来才可以恢复应用代码的执行。也就是说collector“移动对象”这个动作无法与应用代码并发进行。 

如果用read barrier,那移动对象就可以单个单个的进行,而且不需要立即修正所有的指针,所以可以看作整个过程collector都与应用代码是并发的。 

CMS 没有使用read barrier,只用了write barrier。这样,如果它要选用mark-compact为基本算法的话,就只有mark阶段可以并发执行(其中root scanning阶段仍然需要暂停应用代码,这是initial marking;后面的concurrent marking才可以跟应用代码并发执行),然后整个compact阶段都要暂停应用代码。回想最初提到的:compact阶段的时间开销与活对象的大小成正比,这对年老代来说就不划算了。 
于是选用mark-sweep为基本算法就是很合理的选择:mark与sweep阶段都可以与应用代码并发执行。Sweep阶段由于不移动对象所以不用修正指针,所以不用暂停应用代码。 

那 碎片堆积起来了怎么办呢?HotSpot VM里CMS只负责并发收集年老代(而不是整个GC堆)。如果并发收集所回收到的空间赶不上分配的需求,就会回退到使用serial GC的mark-compact算法做full GC。也就是mark-sweep为主,mark-compact为备份的经典配置。但这种配置方式也埋下了隐患:使用CMS时必须非常小心的调优,尽量 推迟由碎片化引致的full GC的发生。一旦发生full GC,暂停时间可能又会很长,这样原本为低延迟而选择CMS的优势就没了。 

新的Garbage-First(G1)GC就是以copying为基础的算法上,把整个GC堆划分为许多小区域(regions),通过每次GC只选择收集很少量region来控制移动对象带来的暂停时间。这样既能实现低延迟也不会受碎片化的影响。 (注意:G1虽然有concurrent global marking,但是可选的,真正带来暂停时间的工作仍然是基于copying算法)

因此在HotSpot VM 只要涉及到对象的移动(copying,compact),就会暂定应用代码(stop-the-world).

 

相关文章:

 

  • 大小: 9.1 KB
  • 大小: 4.8 KB
  • 大小: 325.1 KB
  • 大小: 9.6 KB
  • 大小: 6.4 KB
  • 大小: 3.1 KB
分享到:
评论
1 楼 carlosfu 2016-03-12  
 

相关推荐

    Java虚拟机详解04----GC算法和种类【重要】 - 千古壹号 - 博客园.html

    Java虚拟机详解04----GC算法和种类【重要】,有助于更深入理解记忆,文字配图片,10分钟让你记住gc工作机制。

    深入理解Java虚拟机---学习感悟以及笔记

    这里我们使用举例来说明为什么要学习Java虚拟机,其实这个问题就和为什么要学习数据结构和算法是一个道理,工欲善其事,必先利其器。曾经的我经常害怕处理内存溢出的问题,因为不知道他为什么会出现这个问题,当我在...

    深入java虚拟机

    1. JVM调优 ...3.1 通过Java/JMX得到full GC次数? 3.2 如何更快的启动eclipse 4. JVM基础 4.1 JVM内存管理:深入Java内存区域与OOM 4.2 JVM内存管理:深入垃圾收集器与内存分配策略 4.3 深入理解JVM

    java虚拟机知识点整理

    虚拟机GC垃圾回收收集算法(内存回收方法论) 虚拟机GC垃圾回收收集器(内存回收具体实现) 对象内存分配 虚拟机性能监控与故障处理工具 内存溢出问题及调优 类文件结构 虚拟机类加载机制 编译期编译优化 运行期优化 ...

    java虚拟机

    是垃圾收集的主要区域("GC 堆"),现代的垃圾收集器基本都是采用分代收集算法,该算法的思想是针对不同的对象采取不同的垃圾回收算法,因此虚拟机把 Java 堆分成以下三块: - 新生代(Young Generation) - 老年代...

    深入理解JVM内存结构及运行原理全套视频加资料.txt

     第37讲 垃圾回收算法-标记整理算法和分代收集算法 00:05:24  第38讲 垃圾收集器-serial收集器详解 00:09:45  第39讲 垃圾收集器-parnew收集器详解 00:04:53  第40讲 垃圾收集器-parallel收集器详解 00:11:...

    JVM优化|java虚拟机优化

    - 了解下我们为什么要学习JVM优化 - 掌握jvm的运行参数以及...- 掌握垃圾会回收的常见算法 - 学习串行、并行、并发、G1垃圾收集器 - 学习GC日志的可视化查看 - Tomcat8的优化 - 看懂Java底层字节码 - 编码的优化建议

    Java虚拟机

    这里我们使用举例来说明为什么要学习Java虚拟机,其实这个问题就和为什么要学习数据结构和算法是一个道理,工欲善其事,必先利其器。曾经的我经常害怕处理内存溢出的问题,因为不知道他为什么会出现这个问题,当我在...

    深入理解理解java虚拟机

     java所使用的垃圾回收算法。  基本思想:通过一系列的名为“GC Root”的对象作为起点,从这些节点向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Root没有任何引用链相连时,则该

    Java虚拟机筑地篇之垃圾收集算法

    上一篇介绍了Java虚拟机的运行时内存区域,接下来将来学习下几种常见的垃圾收集算法,进入正题。 概述 在早期,人们就在思考GC(Garbage Collection,GC)需要完成的三件事: 哪些内存需要回收? 什么时候回收? ...

    Java Garbage Collection 与各种GC算法.zip

    这得益于Java虚拟机(JVM),它充当了代码和底层硬件之间的中介。 面向对象: Java是一种纯粹的面向对象编程语言,支持封装、继承和多态等面向对象的概念。这使得Java编写的代码更加模块化、可维护和可扩展。 多...

    Java-jvm.png

    java jvm 优化思维导图,包含java 虚拟机所有知识点,如类加载、垃圾回收(垃圾回收算法、垃圾处理器、GC种类、GC常用参数及配置、GC问题排查等)、内存布局等

    GC垃圾收集器.xmind

    GC垃圾收集器+GC垃圾收集算法,配合java虚拟机一起看,效果更佳,内容简洁,重要,应届小白面试必备技能

    Java八股文的面试题

    Java虚拟机(JVM): JVM是运行所有Java程序的虚拟机环境,实现了Java的跨平台特性。JVM负责将Java字节码转换为机器码执行,同时提供内存管理和垃圾回收等功能。 垃圾回收(GC): Java通过垃圾回收机制自动管理内存,...

    JVM体系结构与GC调优

    JVM体系结构与GC调优相关介绍,包含JVM体系结构、常用GC算法、内存管理、垃圾回收器、虚拟机调优、相关监控工具等

    Java 虚拟机面试题全面解析(干货)

    Java 虚拟机面试题全面解析,《深入理解Java虚拟机》干货版,自己总结,希望能够帮助大家,免费下载~什么是类加载机制? 虚拟机和物理机的区别是什么? 运行时栈帧结构 Java方法调用 什么是方法调用? Java的方法调用,...

    深入学习JVM(Java虚拟机)内核教程

    2.JVM运行机制.mp4 3.常用JVM配置参数.mp4 4.GC算法与种类.mp4 5.GC参数.mp4 6.类装载器.mp4 7.性能监控工具,mp4 8.Java堆分析.mp4 9.锁.mp4 10.Class文件结构.mp4 11.字节码执行.mp4

Global site tag (gtag.js) - Google Analytics