`
steven19880224
  • 浏览: 12108 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java垃圾收集器与内存分配策略(2)

jvm 
阅读更多

 

java垃圾收集器与内存分配策略

 

1. 根搜索算法(GC Roots Tracing)

java语言中判定一个对象是否存活,用的是根搜索算法。

算法思路:从一系列名为“GC Roots”的对象作为起始点,开始向下搜索,搜索经过的路线称为引用链。当一个对象到GC Roots没有任何应用链相连,则证明此对象是不可用的。

可以作为GC Roots的对象包括:

(1)虚拟机栈(栈帧中的本地变量表)中的引用的对象。

(2)方法区中的类静态属性引用的对象。

(3)方法区中常量引用对象。

(4)本地方法栈中JNI(native方法)的引用对象。

对象不可用并不是代表一个对象已经死亡,可以进行回收,在这之前至少要经历两次标记过程:如果对象被宣告为不可用,那它将会被第一次标记并进行第一次筛选,筛选条件是此对象是否有必要执行finalize()方法。当对象没有覆盖该方法,或者该方法已经被虚拟机执行,则这两种情况都被视为“没有必要执行”。

如果这个对象被判定为有必要执行finalize()方法,那么这个对象将被放置在一个名为F-Queue的队列中,并在稍后由一条由虚拟机自动创建的、低优先级的Finalizer线程去执行,但是虚拟机不会阻塞在该方法上,这是为了避免由于finalize()方法执行时间过长或者死循环造成的内存回收系统崩溃。finalize()是对象逃逸的最后一次机会。如果对象在finalize()方法成功的将自己和引用链连接上,那么在F-Queue上的第二次标记时,它将被移出即将回收的集合。还有一点要注意的是finalize()方法对于一个对象而言只会执行一次。

 

2. 引用的类型

jdk1.2以后java对引用的概念进行了扩充:

(1)强引用(Strong Reference):在程序代码中普遍存在的。类似“Object obj = new Object()”,这类引用只要存在垃圾收集器永远不会回收。

(2)软引用(Soft Reference):一些还有用,但并非必须的对象。系统将在发生内存溢出异常之前,将这些对象列进回收范围之中并进行第二次回收。如果回收后还没有足够内存,才抛出异常。

(3)弱引用(Weak Reference):也是描述非必须对象,被弱引用关联的对象只能生存到下一次垃圾收集之前。

(4)虚引用(Phabntom Reference):最弱的引用关系。为一个对象设置虚引用的唯一目的就是希望能在这个对象被回收时收到一个通知。

 

 3.垃圾收集算法

3.1 标记-清除算法(Mark-Sweep)

首先标记出要回收的对象,在标记完成后统一回收掉被标记的对象。

缺点:效率问题,标记和清除效率都不高。导致产生大量不连续的内存碎片。

3.2 复制算法

将空间容量等量的划分成两块,每次使用其中一块。当当前块用完时,将存活对象复制到另外一块,然后将前面一块清理掉。

优点:实现简单、运行高效。

缺点:内存缩小了一半,空间代价高昂。

现在的商业虚拟机都采用这种方法来回收新生代。新生代的对象一般都是朝生夕死,所以不需要1:1的划分空间。而是将分为较大的一块为Eden,两块较小为Survivor空间,每次使用一块Survivor,回收时将Eden和Survivor中存活对象复制到另外一块Survivor空间。HotSpot默认Eden:Survivor=8:1。但是也有可能会出现Survivor大小不足以满足一次复制的需求,这就需要依赖其他内存(这里指老年代)进行分配担保(Handle Promotion),一旦出现这种Survivor空间不够的情况,这些对象将直接进入老年代。

3.3 标记-整理算法

复制算法在对象存活率较高时就要执行较多的复制操作,效率就变低。如果Survivor空间不足还需要额外的空间分配担保。所以根据老年代的特点,运用“标记-整理”算法。标记过程和前面提到的标记算法一致,后面将存活对象都移动到空间的一段,然后清理另一端。

4.垃圾收集器

(1)Serial收集器:用户线程将暂停,GC为单个线程。

(2)ParNew收集器:Serial收集器的多线程版本。用户线程将暂停,在新生代收集时GC为多个线程。

(3)Parallel Scavenge收集器:并行的多线程收集器。其他收集器关注缩短收集时用户线程暂停时间,而此收集器的目标是到达一个可控的吞吐量(Throughput),就是cpu用于用户的时间与CPU总消耗时间的比值。

(4)Serial Old收集器:Serial收集器的老年代版本。单线程。

(5)Parallel Old收集器:Parallel Scavenge收集器的老年代版本。多线程。

(6)CMS(concurrent Mark Sweep)收集器:最短回收时间为目标的收集器。垃圾收集过程分为4个过程:

  • 初始标记:标记GC Roots能直接关联到的对象,速度快。单线程。不可以与用户线程一起工作。
  • 并发标记:进行GC Roots Tracing的过程。单线程。可以与用户线程一起工作。
  • 重新标记:修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段停顿时间一般比初始标记稍长,但是远比并发标记时间段。多线程。不可以与用户线程一起工作。
  • 并发清除:时间最长,收集器线程可以与用户线程一起工作。单线程。
并发标记和并发清除耗时最长。Serial和ParNew能够和它配合使用。
(7)G1收集器:不牺牲吞吐量的前提下完成低停顿的的内存回收。G!将整个堆划分为多个大小固定的区域,根据垃圾堆积程度,在后台维护一个优先列表,每次在允许的收集时间,优先回收垃圾最多的区域。

5.内存分配与回收策略

(1)在新生代进行Minor GC。发生频繁,回收速度也比较快。老年代进行Full GC,经常会伴随一次Minor GC,也叫Major GC一般比Minor GC慢10倍。

(2)多数情况下,对象直接在新生代Eden区中分配。当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC。当Survivor区空间不足时,Minor GC将对象存入老年代。

(3)大对象直接进入老年代。虚拟机提供参数-XX:PretenureSizeThreshold参数设定,如果大于这个参数,怎对象直接进入老年代。
(4)长期存活的对象将进入老年代。如果对象在Eden出生并经过第一次Minor GC后仍然能存活,并被Survivor容纳,将被移动到Survivor区,并将年龄增加1,对象每熬过一次Minor GC年龄就加1。当年龄增加到一定程度时,将被晋升到老年代。这个阀值可以通过设置参数-XX:MaxTenuringThreshold来设置。但是也存在动态的年龄判定,如果Survivor空间中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象直接进入老年代,无须等到满足该参数。
(5)空间分配担保:发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则直接进行一次Full GC。如果小于,则查看HandlePromotionFailure设置是否允许担保失败。如果允许,只进行Minor GC。如果不允许,则也要改为一次Full GC。前面提到,当Survivor空间不足时,就要在老年代中分配担保。这样也会经历刚刚分析的过程。
分享到:
评论

相关推荐

    【Java正来-Java虚拟机专题】-Java垃圾收集器与内存分配策略

    主要整理内容为:分析了垃圾收集的算法和JDK1.7中提供的7款垃圾收集器的特点以及运作原理。以及内存分配策略

    JAVA 垃圾收集器与内存分配策略.rar

    了解和掌握Java的垃圾收集器与内存分配策略对于开发高性能、稳定的应用至关重要,这涉及到程序的运行效率、内存消耗和避免内存泄漏等问题。通过理解这些概念,开发者可以更好地理解和解决Java应用程序中的内存问题,...

    JAVA垃圾收集器与内存分配策略详解

    Java垃圾收集器与内存分配策略是Java性能优化的重要组成部分。垃圾收集器的主要任务是自动管理Java应用程序的内存,确保程序运行过程中有效地回收不再使用的对象,从而避免内存泄漏。本文将详细讲解Java垃圾收集器的...

    JVM初探- 内存分配、GC原理与垃圾收集器

    JVM内存管理是Java虚拟机的核心机制之一,其主要包含对象的创建、内存分配、...通过对内存分配策略、对象生死判定、垃圾收集算法和垃圾收集器的理解与应用,可以更好地掌握JVM的内存管理,从而提升应用性能和稳定性。

    Java垃圾收集器推荐.pdf

    本文将探讨Java垃圾收集器的推荐使用方法,分析其特点与实现机制,以及如何根据应用程序的需求来选择合适的垃圾收集策略。 Java垃圾收集器的主要职责是自动回收程序中不再使用的对象所占用的内存空间,以防止内存...

    笔记,2、垃圾回收器和内存分配策略3

    《垃圾回收器与内存分配策略详解》 在Java编程中,理解垃圾回收(Garbage Collection,简称GC)机制和内存分配策略是至关重要的。GC的主要目的是自动管理内存,避免程序员手动进行繁琐且容易出错的内存释放工作。而...

    笔记,2、垃圾回收器和内存分配策略1

    《垃圾回收器与内存分配策略详解》 在Java编程中,理解垃圾回收(Garbage Collection,简称GC)机制和内存分配策略是至关重要的。GC的主要目的是自动管理内存,避免程序员手动进行繁琐且容易出错的内存释放工作。而...

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

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

    Java垃圾收集器知识.pdf

    Java垃圾收集器是Java编程语言的核心特性之一,它自动化地管理程序的内存空间,极大地简化了内存管理的工作,避免了手动回收内存可能导致的错误和内存泄漏问题。以下是对Java垃圾收集器的详细解析: 1. **工作原理*...

    Java垃圾收集器参考.pdf

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

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

    Java垃圾收集器是Java语言中的一个关键特性,它负责自动管理程序中的内存,尤其是对象的分配和回收。在一些编程语言中,如C++,在堆上分配对象可能需要较高的开销,但在Java中,由于垃圾收集器的存在,这个过程实际...

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

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

    java程序中的内存分配问题

    8. **内存泄漏**:虽然Java有垃圾收集器,但不正确的编程习惯可能导致内存泄漏,例如静态集合类中存储大量无用对象,或者线程池未关闭等。找出并修复内存泄漏是提升程序性能的重要环节。 9. **Java内存模型(JMM)*...

    java实现的内存分配

    Java提供了几种不同的垃圾收集器,如Serial、Parallel、Concurrent Mark Sweep (CMS) 和G1等,它们各有优缺点,适用于不同的场景。例如,Serial GC适合小型应用,而CMS和G1则更适合大型并发环境。 此外,Java还提供...

    计算机科学与技术-外文翻译-外文文献-英文文献-Java垃圾收集器的工作方式.doc

    Java垃圾收集器是Java语言中一个关键的特性,它负责管理程序运行时的内存空间,尤其是对象的分配和回收。在传统的编程语言如C++中,堆内存的管理需要程序员手动进行,分配和释放对象可能会涉及到复杂的内存操作,...

    java内存分配演示程序

    9. **Java虚拟机参数调整**:开发者可以通过JVM参数来调整内存分配策略,例如-Xms和-Xmx设置堆内存的初始大小和最大大小,-XX:NewRatio设置新生代和老年代的比例等。 10. **JVM内存诊断工具**:JVisualVM、jmap、...

    Java的垃圾收集器(GC)参考.pdf

    Java的垃圾收集器(GC)是Java编程语言的一个核心特性,它自动化地管理程序的内存分配和回收,显著减轻了程序员手动管理内存的负担。在Java中,内存管理主要是通过垃圾收集器来实现的,它负责检测并回收不再使用的...

    JAVA内存模型与垃圾回收

    Java提供了多种垃圾收集器,如Serial、ParNew、Parallel Scavenge、CMS(Concurrent Mark Sweep)、G1(Garbage-First)等,每种收集器都有其特点和适用场景。选择合适的垃圾收集器配置可以优化应用程序的性能和响应...

    java垃圾收集与异常处理

    Java垃圾收集与异常处理是Java编程中至关重要的概念,它们对于程序的稳定性和性能有着直接影响。垃圾收集(Garbage Collection, GC)是Java虚拟机自动管理内存的一种机制,而异常处理则是通过预设的错误处理流程来...

Global site tag (gtag.js) - Google Analytics