`
chenjingbo
  • 浏览: 460639 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

我所理解的java的垃圾收集

阅读更多


 说明:本篇文章,有很多错误.排版也不合理.请批判的阅读. (有空再整理了)

1 四种垃圾回收算法

      PS 这里介绍了4中垃圾回收算法,不代表就只有这四种。

(1)引用计数( Reference Counting )算法

     这个算法在很多面试宝典里频繁出现,当年我也被宝典所迷惑。一直到后面听同事的讲座才明白原来JAVA压根就没用这个算法作为其垃圾回收算法。但是为了本文相对的完整性,还是拿出来说一下。

    引用计数法是唯一没有使用根集的垃圾回收的法,该算法使用引用计数器来区分存活对象和不再使用的对象。一般来说,堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器每次加1当对象出了作用域后(该对象丢弃不再使用),引用计数器减1,一旦引用计数器为0,对象就满足了垃圾收集的条件。 

    该算法的优点是速度快,不会中断程序执行(也就是传说中的stop the world)。但是缺点也很明显:算法对程序中每一次内存分配和指针操作提出了额外的要求(增加或减少内存块的引用计数)。更重要的是,引用计数算法无法正确释放循环引用的内存块(这个问题可以在我的这篇blog里详细说明了http://chenjingbo.iteye.com/blog/1119059

(2)tracing算法(Tracing Collector)

    tracing算法是为了解决引用计数法的问题而提出,它使用了根集的概念。基于tracing算法的垃圾收集器从根集开始扫描,识别出哪些对象可达,哪些对象不可达,并用某种方式标记可达对象,例如对每个可达对象设置一个或多个位。

 

    在这里也顺便说下java中,可作为GC Root的对象

    1>虚拟机栈中引用的对象。虚拟机栈可以粗略的理解为java方法执行的内存模型。也就是说当前正在执行的方法中所引用的对象。

    2>方法区中的类静态属性所引用的对象

    3>方法区中的常量引用的对象

    4>本地方法栈中JNI(一般可以理解为native方法)的引用的对象

 

    标记和清除算法的缺点很明显,一是效率,因为标记和清除的效率都不高;二是碎片问题。因为清除之后会产生很多不连续的内存碎片。对于第二个碎片问题,人们想到了另外一个算法,是对标记清除算法的改善,就是下面说的标记-整理算法

(3) compacting算法(Compacting Collector)

     compacting算法也叫标记-整理算法。

    为了解决堆碎片问题,基于tracing的垃圾回收吸收了Compacting算法的思想,在清除的过程中,算法将所有的对象移到堆的一端,堆的另一端就变成了一个相邻的空闲内存区,收集器会对它移动的所有对象的所有引用进行更新,使得这些引用在新的位置能识别原来 的对象。在基于Compacting算法的收集器的实现中,一般增加句柄和句柄表。

    标记-整理算法是后面说的旧生代采用的垃圾收集算法。

(4)copying算法(Coping Collector)

      复制算法是为了克服句柄的开销和解决堆碎片的垃圾回收。它将可用内存按照容量划分为相同大小的两块。每次只使用其中一块,当这一块的内存用完了,就将存活的对象复制到另外一块,然后把自己这块内存给清理掉。这样的好处很明显,每次都只对其中的一块进行内存回收,内存分配也不需要考虑碎片等问题,只要移动指针,按照顺序分配内存即可,效率很高。但是它的缺点更明显,会将内存缩小为原来的一半。

    现在所有的商业虚拟机都采用这种算法来回收新生代。

2 现在的jvm在垃圾收集上采用了何种方式

    现在的商业虚拟机的垃圾回收都采用“分代收集”方式。这个算法并没有新的思想,只是将存活周期不同的对象分为不同的几块。所以我就不将这个看做一个垃圾收集的算法。

    大家都知道,java的对象存放在java堆(Java Heap)中。而JAVA堆的描述如下:


 整个Heap可以分为两个部分:Heap = {Old + NEW = { Eden , from, to } }


 在很多资料中 Old Space也叫old generation。翻译成中文叫老年代,旧生代。而 Eden + from + to 组成了 New Space 也叫 new generation ,翻译成中文就是年轻代,新生代。至于上图中的 NewRatio,SurvivorRatio之类的参数,都是可以通过-XX:NewRatio=8 -XX:SurvivorRatio等参数配置的。这篇文章里就不多说了。主要关心的是 old Space,Eden,Fromspace,Tospace这四个名词。

还有一个名词需要解释清楚,FromSpace + ToSpace = Suvivor

 

------------------------------------------------我是分割线,下面可以讲真正的垃圾收集-------------------------------------

 

      几乎所有对象的创建都是在新生代被分配内存的(大对象直接分配在旧生代)。IBM的专门研究表明,新生代中的对象98%是朝生夕死的。所以现在的商业虚拟机都是采用复制算法来回收新生代,而且,也不需要按照1:1的比例来划分内存空间,而是将heap划分为一块较大的Eden和两块较小的Survivor(也就是上面的FromSpace和ToSpace)。当进行gc的时候,将Eden和Survivor中的某一块(FromSpace)中存活的对象复制到另一块Survivor内存(ToSpace)中。这个时候,一次MinorGC(也就是新生代GC)就算完成了,原来的FromSpace就变成ToSpace,而ToSpace变成FromSpace。在进行了几次GC(系统默认是15次,可以通过-XX:MaxTenuringThreshold来设置)后依旧存在的对象则会被移动到旧生代。当然,还有动态对象年龄判断来判定对象是否进入旧生代。

     这里需要说明的是:系统默认的Eden与Survivor的比例是8:1,也就是每次新生代中可用的内存空间为整个新生代内存的90%,只有10%的内存是被浪费的。这样比纯粹的复制算法(50%)好很多。

     年老代的GC又叫Full GC或者Major GC。一般情况下,发生FullGC的时候会伴随一次MinorGC(也就是年轻代GC)。上面已经说了Full GC的算法采用的是标记-整理算法(据说还有标记-清理算法)。而且从效率上来说,一般情况下会比Minor GC慢10倍以上。

 

 

    最后说一下,上面说的都是垃圾收集算法,换句话说上面说的都是方法论,具体的实现就是对应具体的垃圾收集器。JAVA的虚拟机规范中并没有规定应该如何实现垃圾收集器,所以不同的厂商,不同版本的虚拟机所提供的垃圾收集器都有可能有很大的不同。最后放一个图说明下Sun 的 HotSpot虚拟机1.6 Update22所包含的收集器。这幅图是sun的某人在2008年2月画的,其中的问号现在已经基本可以确定是G1收集器。因为JDK1.6 Update14就引入了G1的 Early Access版。据说JDK7推出以后,会有一个商业版的G1收集器出来,大家期待吧

 

 

 

 

  • 大小: 11.6 KB
  • 大小: 82.8 KB
分享到:
评论

相关推荐

    深入理解JVM垃圾收集算法与垃圾收集器

    深入理解JVM垃圾收集算法与垃圾收集器

    Java理解G1垃圾收集器.pdf

    Java的G1(Garbage First)垃圾收集器是一种先进的垃圾回收机制,主要设计目标是实现低延迟、高吞吐量的内存管理。G1垃圾收集器是Java虚拟机(JVM)...在Java应用的性能调优中,理解和配置好G1垃圾收集器是至关重要的。

    Java的垃圾收集器(GC)

    总之,垃圾收集器是Java生态系统中不可或缺的一部分,深入理解和合理运用GC机制,对于构建高效、稳定的Java应用程序至关重要。随着Java技术的不断演进,GC也将持续优化,为开发者带来更加便捷的开发体验。

    Java垃圾收集器推荐.pdf

    Java垃圾收集器的主要职责是自动回收程序中不再使用的对象所占用的内存空间,以防止内存泄漏和优化内存资源的利用。垃圾收集器通过监控对象的引用情况来判定一个对象是否可以被回收。当一个对象没有任何活动引用指向...

    【Java技术资料】-Java垃圾收集必备手册

    Java垃圾收集是Java编程中的一个核心概念,...这份手册可能深入讲解了以上知识点,并提供了实践案例和最佳实践,帮助开发者更好地理解和掌握Java垃圾收集。学习和理解这些内容对于提升Java应用的性能和稳定性至关重要。

    Java垃圾收集必备手册.rar

    通过深入学习这份"Java垃圾收集必备手册",开发者可以更好地理解Java内存管理机制,提升程序性能,避免因内存问题导致的系统崩溃或性能下降。对于大型分布式系统或者对响应时间有严格要求的项目,掌握垃圾收集的原理...

    java垃圾收集与异常处理

    综上所述,Java垃圾收集与异常处理是Java程序员必须掌握的核心技能。理解GC的工作原理和调优方法,以及合理地使用异常处理机制,能够帮助我们编写出更加健壮和高效的代码。在实际开发中,结合具体的业务需求和系统...

    java垃圾收集机制

    ### Java垃圾收集机制详解 #### 一、引言 在现代软件开发中,Java作为一种广泛使用的编程语言,其自动管理内存的功能极大地简化了程序设计工作。传统的编程语言如C/C++要求开发者手动管理内存,这不仅增加了编程的...

    Java垃圾收集必备手册

    Java垃圾收集机制的深入理解和调优对于构建高性能、稳定的Java应用至关重要。了解不同垃圾收集算法的原理和特点,合理使用JVM提供的工具和参数进行调整,是每位Java开发者都需要掌握的技能。此外,由于不同版本的JVM...

    计算机专业外文翻译(Java垃圾收集器)

    Java垃圾收集器是Java语言中的一个关键特性,它负责自动管理程序中的内存,尤其是在对象生命周期结束时进行内存的释放。这篇3000字的毕业设计论文外文翻译主要探讨了Java垃圾收集器的工作原理及其对性能的影响。 在...

    Java垃圾收集器知识.pdf

    理解并熟练掌握Java垃圾收集器的工作原理和特性对于开发高性能、稳定的Java应用至关重要,尤其是在处理大量对象和大数据量的场景下。通过深入学习和实践,开发者可以更好地优化程序的内存使用,减少垃圾收集对应用...

    Java垃圾收集概述.pdf

    总的来说,理解Java垃圾收集的工作原理和优化策略对于提高Java应用的性能至关重要。开发者需要了解不同类型的垃圾收集器及其特性,以便根据应用的具体需求选择合适的配置,同时通过合理设计数据结构和算法,减少不必...

    Java垃圾收集器参考.pdf

    Java垃圾收集器是Java语言的核心特性之一,它自动化地处理内存管理,使得程序员无需手动回收内存,从而减少了潜在的内存泄漏问题。Java虚拟机(JVM)中的垃圾收集器通过一个低优先级的线程——垃圾收集器线程来监控...

    【深入Java虚拟机(8)】Java垃圾收集机制编程开发技

    Java垃圾收集机制是...综上所述,Java垃圾收集机制是JVM的重要组成部分,理解其工作原理和调优技巧对于优化程序性能、防止内存泄漏和内存溢出至关重要。开发者应深入学习并掌握这一主题,以便在实际开发中游刃有余。

    Java垃圾收集必备手册.pdf

    本文档是一本关于Java垃圾收集的教程,主要涉及了垃圾收集的概念、算法以及调优技巧。垃圾收集是Java内存管理的一个重要方面,它能够自动回收堆内存中不再使用的对象,减少内存泄漏的风险。本手册提供了一个全面的...

    一篇文章教你深入理解Java垃圾收集(GC)机制.docx

    Java垃圾收集(GC)机制是Java编程中至关重要的一部分,它负责自动管理程序的内存,确保不再使用的对象能够被及时回收,以避免内存泄漏。GC主要关注的是Java堆和方法区这两部分内存,因为它们是动态分配和回收的。 ...

    1_Java虚拟机(垃圾收集器和算法).pdf

    本文详细探讨了JVM中的垃圾收集器和垃圾收集算法,以帮助开发者深入理解Java虚拟机的内部运作机制。 垃圾收集(GC,Garbage Collection)是JVM的一个重要功能,用于自动释放不再使用的对象所占用的内存空间,以防止...

    理解Java垃圾回收

    理解Java垃圾回收机制对于编写高效、健壮的Java程序至关重要。开发者需要了解垃圾回收的工作原理,避免产生内存泄漏,并合理调整垃圾回收参数以适应应用程序的需求。在实际开发中,结合内存分析工具(如VisualVM、...

    JAVA垃圾回收机制

    Java垃圾收集器有多种类型,包括: 1. 标记-清除收集器:遍历对象图标记存活对象,然后清理未标记对象,可能导致内存碎片。 2. 标记-压缩收集器:类似于标记-清除,但清理后会压缩存活对象,减少碎片。 3. 复制收集...

Global site tag (gtag.js) - Google Analytics