`
chenjingbo
  • 浏览: 458802 次
  • 性别: 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技术资料】-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垃圾收集器推荐.pdf

    Java垃圾收集器是Java语言的重要特性,它负责自动管理程序中的内存空间,避免手动内存管理带来的问题,如内存泄漏。垃圾收集器通过一个系统级的线程——垃圾收集线程来工作,它会在Java虚拟机(JVM)空闲时检查并...

    一篇文章教你深入理解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