JVM内存分配与垃圾回收策略(带图解)

1. 内存分配策略

①小对象优先进入eden区( + 空间分配担保)

②大对象直接进入老年代

    可以通过参数设置

③长期存活对象将晋升老年代

    可以通过参数设置

④动态年龄判定

    如果在Survivor空间中低于或等于某年龄的所有对象大小和总和大于Survivor空间的一半,则年龄大于等于该年龄的对象就可以直接进入老年代。

2. 如何判断对象已死亡?

①引用计数法

    引用+1,引用失效-1,为零回收。优点简单高效,缺点无法解决循环引用问题

②可达性分析法

    两次标记(不可达对象并非非死不可,可以自我拯救)

3. 引用:强软弱虚

·强引用:jvm宁愿排除oom异常也不会回收的对象引用

·软引用:可有可无的引用,例如用作cache。如果内存足够,则不会回收,当内存不够则回收,以时间换空间(使用缓存一般是节省读取时间或者节省计算时间)。

·弱引用:可有可无。GC线程扫描到就会收回,无论内存是否充足。

·虚引用:形同虚设,主要用来跟踪对象被垃圾回收的活动。

    在程序设计中一般很少使用弱引用与虚引用,使用软引用的情况较多,这是因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生


4. 方法区类型卸载

三个条件才允许卸载:(仅允许,但不一定会卸载)

    ①该类实例对象被回收

    ②该类的类加载器被回收

    ③该类的class对象已经不在被引用,无法在任何地方通过反射访问该类的方法


5. 垃圾回收算法

①标记-清除

缺点:效率问题、空间问题(空间碎片,不利于后续大对象的空间分配)

(效率问题体现在执行效率不稳定,当扫描范围内大部分对象需要被清除的时候需要进行大量标记和清除的动作,复制和整理可以整片清除)

②标记-复制

半区复制、eden和survivor区(有分配担保机制)

③标记-整理

让存活的对象都向内存空间一端移动(虽然内存回收复杂,停顿时间长,但是由于空间规整,在内存分配较为简单,速度快,因此吞吐量是高的)


6. 什么要分为新生代和老年代?

    因为分代可以根据不同年代的特点选择更加合适的垃圾回收算法。
    比如新生代,大部分对象都朝生夕灭,因此如果采取标记-复制算法,只需要付出少量的对象复制成本就可以完成每次垃圾回收而又不产生较多的空间碎片。而老年代的对象存活率较高,而且没有额外的空间对其进行分配担保,因此采用标记-清除标记-整理算法更加合适。


7. 经典垃圾收集器


①Serial

·特点:(1)单线程(2)“stop the world”

·优点:简单高效,没有线程交互开销。适合Client模式

·GC区域及方法:【新生代】标记-复制


②Serial old

·特点:老年代的Serial收集器 单线程。作为CMS收集器“并发失败”的后备预案

·GC区域及方法:【老年代】标记-整理


③ParNew

·特点:多线程并行,但GC时仍然需要暂停其它工作线程

·GC区域及方法:【新生代】标记-复制


④Parallel Scavenge (吞吐量优先收集器)

·特点:

和ParNew收集器非常相似。特别之处在于其目标是达到一个可控制的吞吐量。

·注意点:

吞吐量=运行用户代码时间 / (运行用户代码时间 + GC时间)

可以设置最大垃圾收集停顿时间、吞吐量大小(也可以让系统自动设置)

(垃圾收集停顿时间的缩短是以牺牲吞吐量和新生代空间为代价换取的)

·GC区域及方法:【新生代】标记-复制


⑤Parallel Old

·特点:Parallel Scavenge收集器的老年代版本。

在注重吞吐量和处理器资源较为稀缺的场合,可以优先考虑Parallel Scavenge + Parallel Old这个组合。

·GC区域及方法:【老年代】标记-整理


⑥CMS

·特点:

    目标是尽可能地缩短GC时用户线程的停顿时间、加快服务响应速度,是第一款能与用户线程并发执行的GC收集器。

·GC区域及方法:【老年代】标记-清除

·步骤:

(1)初始标记:标记与GC Roots直接相连的对象

(2)并发标记:与工作线程一起,对扫描空间进行可达性分析。

(3)重新标记:重新标记并发标记期间出现的增量更新。

(4)并发清除:与工作线程一起,对标记对象进行清除。


·缺点:

(1)对处理器资源非常敏感

    线程数=(n + 3)/ 4。当核心数少于4时会占用较大运算资源

(2)无法处理浮动垃圾

    并发标记阶段会产生的增量垃圾。因此需要设置合适的CMS启动阈值。

    太小会导致GC过于频繁,太大会导致”并发失败”会启动后备预案Serial Old, 增加停顿时间。

(3)产生大量空间碎片

    大对象没有连续空间存放时会触发Full GC


⑦G1 (Garbage-First)

·特点(优点):

1、可以指定最大停顿时间

2、基于Region的内存布局形式

3、按各Rigion回收价值动态确定回收集,建立了“预测停顿”模型

4、不需要其它GC收集器配合

·GC区域:

跨越整个新生代+老年代。化整归零,新生代和老年代不再固定,而是一系列区域的动态集合。

·GC方法:

整体上看基于标记-整理,局部上看基于标记-复制。


·GC步骤:

(1)初始标记

(2)并发标记

(3)最终标记

(4)筛选回收:多线程并行,当需要stop the world

    G1收集器在后台维护了一个优先列表,存放各rigion近期的回收价值数据, 每个GC时根据设定的GC停顿时间来选择优先选择回收价值最大的Rigion,动态 确定会收集。


·缺点:

(1)内存占用高

每个rigion都需要使用卡表来处理跨代指针,可能会额外占用整个堆的20%的空间。因此适合内存较大的服务器模式JVM。

(2)执行负载大

与G1的原始快照搜索算法产生的额外开销负担有关,有点记不清了,需要回忆一下。


·适用场景:

适用于核心数较多的处理器以及配备大容量内存的服务器。



你可能感兴趣的:(JVM内存分配与垃圾回收策略(带图解))