`
m635674608
  • 浏览: 5005166 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

各种Java垃圾回收器的比较

    博客分类:
  • java
 
阅读更多

现在已经是2014年了,但是对大多数开发人员而言有两件事情仍然是个谜——垃圾回收以及异性(码农又被嘲笑了)。由于我对后者也不是特别了解,我想我还是试着说说前者吧,尤其是随着Java 8的到来,这个领域也发生了许多重大的变化及提升,其中最重要的莫过于持久代(PermGen)的删除以及一些令人振奋的新的优化(后面会陆续提及这些)。

说起垃圾回收,许多人都了解它的概念,也在日常的编程中有所应用。尽管如此,仍有许多我们不太了解的东西,而这正是痛苦的根源。关于JVM最大的误解就是认为它只有一个垃圾回收器,而事实上它有四个不同的回收器,每个都各有其长短。JVM并不会自动地选择某一个,这事还得落在你我的肩上,因为不同的回收器会带来吞吐量及应用的暂停时间的显著的差异。

这四种回收算法的共同之处在于它们都是分代的,也就是说它们将托管的堆分成了好几个区域,它假设堆中的许多对象的生命周期都很短,可以很快被回收掉。介绍这块内容的已经很多了,因此这里我打算直接讲一下这几个不同的算法,以及它们的长处及短处。

1.串行回收器

串行回收器是最简单的一个,你都不会考虑使用它,因为它主要是面向单线程环境的(比如说32位的或者Windows)以及比较小的堆。这个回收器工作的时候会将所有应用线程全部冻结,就这一点而言就使得它完全不可能会被服务端应用所采用。

如何使用它:你可以打开-XX:+UseSerialGC这个JVM参数来使用它。

2.并行/吞吐量回收器

下一个是并行回收器( Parallel collector)。这是JVM的默认回收器。正如它的名字所说的那样,它的最大的优点就是它使用多个线程来扫描及压缩堆。它的缺点就是不管执行的是minor GC还是full GC它都会暂停应用线程。并行回收器最适合那些可以容许暂停的应用,它试图减少由回收器所引起的CPU开销。

3.CMS回收器

并行回收器之后就是CMS回收器了(concurrent-mark-sweep)。这个算法使用了多个线程(concurrent)来扫描堆并标记(mark)那些不再使用的可以回收(sweep)的对象。这个算法在两种情况下会进入一个”stop the world”的模式:当进行根对象的初始标记的时候 (老生代中线程入口点或静态变量可达的那些对象)以及当这个算法在并发运行的时候应用程序改变了堆的状态使得它不得不回去再次确认自己标记的对象都是正确的。

使用这个回收器最大的问题就是会碰到promotion failure,这是指在回收新生代及年老代时出现了竞争条件的情况。如果回收器需要将年轻的对象提升到年老代中,而这个时候年老代没有多余的空间了,它就只能先进行一次STW(Stop The World)的full GC了——这种情况正是CMS所希望避免的。为了确保这种情况不会发生,你要么就是增加老生代的大小(或者增加整个堆的大小),要么就是给回收器分配一些后台线程以便与对象分配的速度进行赛跑。

这个算法的另一个缺点就是和并行回收器相比,它使用的CPU资源会更多,它使用了多个线程来执行扫描和回收,这样才能让应用持续提供更高级别的吞吐量。对于大多数长期运行的程序而言,应用的暂停对它们是很不利的,这个时候可以考虑使用CMS回收器。尽管如此,这个算法也不是默认开启的。你得指定XX:+UseConcMarkSweepGC来启用它。假设你的堆小于4G,而你又希望分配更多的CPU资源以避免应用暂停,那么这就是你要选择的回收器。然而,如果堆大于4G的话,你可能更希望使用最后的这个——G1回收器。

4.G1回收器

G1( Garbage first)回收器在JDK 7update 4中首次引入,它的设计目标是能更好地支持大于4GB的堆。G1回收器将堆分为多个区域,大小从1MB到32MB不等,并使用多个后台线程来扫描它们。G1回收器会优先扫描那些包含垃圾最多的区域,这正是它的名字的由来(Garbage first)。这个回收器可以通过-XX:UseG1GC标记来启用。

这一策略减少了后台线程还未扫描完无用对象前堆就已经用光的可能性,而那种情况回收器就必须得暂停应用,这就会导致STW回收。G1的另一个好处就是它总是会进行堆的压缩,而CMS回收器只有在full GC的时候才会干这事。

过去几年里,大堆一直都是一个充满争议的领域,很多开发人员从单机器单JVM模型转向了单机器多JVM的微服务,组件化的架构。这是许多因素所驱动的,包括隔离程序的组件,简化部署,避免重新加载应用类到内存所产生的开销(Java 8中这点已经得到了改善)。

尽管如此,这么做最主要还是希望能避免大堆的GC中长时期的”stop the world”的暂停(在一次大的回收中需要花费数秒才能完成)。像Docker这样的容器技术也加速了这一进程,它们使得你可以很轻松地在同一台物理机上部署多个应用。

Java 8及G1回收器

Java 8 update 20所引入的一个很棒的优化就是G1回收器中的字符串去重(String deduplication)。由于字符串(包括它们内部的char[]数组)占用了大多数的堆空间,这项新的优化旨在使得G1回收器能识别出堆中那些重复出现的字符串并将它们指向同一个内部的char[]数组,以避免同一个字符串的多份拷贝,那样堆的使用效率会变得很低。你可以使用-XX:+UseStringDeduplication这个JVM参数来试一下这个特性。

Java 8及持久代

Java 8中最大的改变就是持久代的移除,它原本是用来给类元数据,驻留字符串,静态变量来分配空间的。这在以前都是需要开发人员来针对那些会加载大量类的应用来专门进行堆比例的优化及调整。许多年来都是如此,这也正是许多OutOfMemory异常的根源,因此由JVM来接管它真是再好不过了。即便如此,它本身并不会减少开发人员将应用解耦到不同的JVM中的可能性。

每个回收器都有许多不同的开关和选项来进行调优,这可能会增加吞吐量,也可能会减少,这取决于你的应用的具体的行为了。在下一篇文章中我们会深入讲解配置这些算法的关键策略。

 

 

http://www.php100.com/html/it/biancheng/2015/0507/8954.html

分享到:
评论

相关推荐

    Java垃圾回收机制详解和调优.doc

    Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收...

    Java垃圾回收机制总结

    Java垃圾回收机制总结 Java垃圾回收机制是Java虚拟机(JVM)中的一种机制,用于防止内存泄露和有效地使用空闲的内存。垃圾回收机制的主要目的是为了回收无用的对象占用的内存空间,使该空间可被程序再次使用。 ...

    Java垃圾回收机制

    Java垃圾回收机制的详细介绍,调理比较清晰,个人进行的总结。

    JAVA垃圾回收机制

    Java垃圾回收机制(GC)是Java编程语言的关键特性,它自动管理内存,释放不再使用的对象,以防止内存泄漏。GC的运作方式主要有两种策略:引用计数和对象引用遍历。 引用计数是一种简单但不完美的方法。每个对象都有...

    【Java面试题】Java垃圾回收机制

    【Java面试题】Java垃圾回收机制

    java高级之垃圾回收机制

    本文将详细介绍Java中的垃圾回收机制及其工作原理,并探讨JVM如何管理和优化垃圾回收过程。 #### 二、JVM内存模型 JVM内存模型主要包括永久代(Permanent Generation, PermGen)、堆(Heap)和栈(Stack)三大部分。值得...

    Java中类的生命周期与java垃圾回收机制

    Java中类的生命周期与java垃圾回收机制

    java垃圾回收器代码举例

    Java垃圾回收器(Garbage Collector, GC)是Java编程语言中的一个重要特性,它负责自动管理内存,自动回收不再使用的对象,以防止内存泄漏。在Java中,程序员无需手动释放内存,这一过程由JVM(Java虚拟机)自动完成...

    深入了解Java垃圾回收机制

    Azul Systems CTO & co-Founder, Gil Tene 在SpringOne2GX 2012大会上发表的演讲资料,全面深入地阐述Java垃圾回收的四种机制。并介绍了当今世界上性能与吞吐量最高的JVM产品Zing JVM。 如果希望深入了解Java的垃圾...

    java 垃圾回收机制详细介绍

    垃圾收集器是Java语言区别于其他程序设计语言的一大特色。它把程序员从手工回收内存空间的繁重工作中解脱了出来。在SUN公司的Java程序员(Java Programmer)认证考试中,垃圾收集器是必考的内容,一般最多可以占总...

    Java垃圾回收详解

    ### Java垃圾回收详解 #### 垃圾回收基础概念 在Java编程语言中,垃圾回收(Garbage Collection, GC)是一项自动化的内存管理机制。它能够自动检测并释放那些不再被程序使用的对象所占用的内存空间,从而有效地...

    Java与C#的垃圾回收机制

    ### Java与C#的垃圾回收机制 #### 一、引言 在现代编程语言中,内存管理是一项重要的功能,能够显著提升程序的稳定性和效率。本文将深入对比Java与C#这两种广泛使用的编程语言中的垃圾回收机制,帮助开发者更好地...

    细述 Java垃圾回收机制→Java Garbage Collection Introduction - Android 1

    Java垃圾回收机制简介 Java垃圾回收机制是Java语言中的一种自动内存管理机制,它可以帮助程序员更好地编写Java应用程序,而不需要手动编写垃圾回收相关的代码。这篇文章将会介绍Java垃圾回收机制的基本概念和原理,...

    深入Java核心_探秘Java垃圾回收机制

    #### 二、Java垃圾回收的基本概念 Java的垃圾回收机制主要是为了清除不再使用的对象,其核心思想是通过确定对象是否还有有效的引用路径来决定是否进行回收。这一过程主要涉及以下几个关键步骤: 1. **可达性分析**...

Global site tag (gtag.js) - Google Analytics