JVM —— 垃圾回收

一、分代收集策略

    Java对象:根据生命周期划分为瞬时对象 和生命周期非常长对象。

    考虑JVM中存活对象的生命周期具有两极化,因此采取不同的收集策略——分代收集。

   

    堆区划分

新生代(YoungGen)Eden、From Survivor、To Survivor(Eden和Survivor比例8:1:1)

        老年代(OldGen)

-XX:SurvivorRatio 设置空间比例


二、垃圾标记

    1.引用计数器算法

            引用计数器算法是给每个对象设置一个计数器,当有地方引用这个对象的时候,计数器+1,当引用失效的时候,

            计数器-1,当计数器为0的时候,JVM就认为对象不再被使用,是“垃圾”了。

            引用计数器实现简单,效率高;但是不能解决循环引用问问题(A对象引用B对象,B对象又引用A对象,但是A,

            B对象已不被任何其他对象引用),同时每次计数器的增加和减少都带来了很多额外的开销。


    2.可达性分析算法

        通过一些“GC Roots”对象作为起点,从这些节点开始往下搜索,搜索通过的路径成为引用链

    (Reference Chain),当一个对象没有被GC Roots的引用链连接的时候,说明这个对象是不可用的。


        GC Roots对象包括:
1.Java栈中的对象引用
2.本地方法栈中的对象引用
3.运行时常量池的对象引用
4.方法区中静态属性的对象引用

5.与一个类对应的唯一数据类型的Class对象


三、垃圾回收

    1.标记清除算法

        标记—清除算法包括两个阶段:“标记”和“清除”。在标记阶段,确定所有要回收的对象,并做标记。

        清除阶段紧随标记阶段,将标记阶段确定不可用的对象清除。

        缺点:执行效率低,产生内存碎片


    2.复制算法

复制算法是把内存分成大小相等的两块,每次使用其中一块,当垃圾回收的时候,把存活的对象复制到另

        一块上,然后把这块内存整个清理掉。


        MInor GC:当执行一次Minor GC(新生代的垃圾回收)时,Eden空间中的存活对象会被复制到To空间内,

                           并且之前已经经历过一次Minor GC并在From空间中存活下来的对象如果还年轻的话同样也

                           会被复制到To空间内。

                           首先如果存活对象的分代年龄超过选项“-XX:MaxTenuringThreshold”所指定的阈值时,将

                         直接晋升到老年代中;其次当To空间的容量达到阈值时,存活对象同样也是直接晋升到老年代。

                         剩余的均是垃圾对象这就意味着GC可以对这些已经死亡的对象执行一次MinorGC,释放掉其所

                         占用的内存空间

                        执行MInorGC之后,Eden空间和From空间将会被清空,而存活下来的对象被全部存活在To空间

                           内,接下来From和To空间将会互换位置。


    3.标记压缩算法

       标记压缩算法将所有的存活对象都移动到一个规整且连续的内存空间中然后执行FullGC。

       FullGC: (老年代的垃圾回收)回收无用对象所占用的内存空间。 

四、垃圾收集器

        1.Stop-the-World机制:垃圾收集器会在内存回收过程中暂停所有的工作线程,直至完成内存回收后才恢复

                                                之前被暂停的工作线程。


        2.新生代收集器

            

Serial收集器Serial收集器是一个新生代收集器,单线程执行,使用复制算法。它在进行垃圾收集时,必须暂停其他所有的工作线程(用户线程)也就是传说中的Stop The World。是Jvm client模式下默认的新生代收集器。对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。
ParNew收集器ParNew收集器其实就是serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为与Serial收集器一样。 使用方式可以使用-XX:+UseConcMarkSweepGC,或者是使用-XX:+UseParNewGC来强制开启,可以通过-XX:ParallelGCThreads 来调整或者限制垃圾收集的线程数量。
Parallel收集器                                                                     Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的收集器,又是并行多线程收集器。parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。吞吐量= 程序运行时间/(程序运行时间 + 垃圾收集时间)。

        3.老年代收集器

Serial Old收集器Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用“标记-整理”算法。这个收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server模式下,那么它主要还有两大用途:一种用途是在JDK 1.5以及之前的版本中与Parallel Scavenge收集器搭配使用,另一种用途就是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure时使用。
Parallel Old 收集器Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。
CMS 收集器

CMS收集器是基于“标记—清除”算法实现的,它的运作过程相对于前面几种收集器来说更复杂一些,整个过程分为4个步骤,包括:
初始标记
并发标记
再次标记
并发清除


其中,初始标记、再次标记这两个步骤仍然需要“Stop The World”。


由于使用标记——清除算法,为新对象分配空间采用空闲列表进行内存分配。


考虑内存碎片弊端:
CMS提供“-XX:+UseCMS-CompactAtFullCollection”指定在执行FullGC后是否进行压缩整理


由于压缩整理无法并行执行:
CMS提供“-XX:CMSFullGCs-BeforeCOmpaction”指定多少次FullGC后进行内存空间整理


内存回收:
“-XX:CMSInitiatingOccupancyFraction”指定当老年代中的内存使用率达到多少百分比的时候执行内存回收
(默认值92%)
G1收集器                                                                                        将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。


G1收集器执行过程:
初始标记  ——“stop the world”机制出现短暂的暂停,任务标记Root-Region
根区域扫描——扫描Root-Region中引用老年代的一些Region块
并发标记——找出整个Java堆区中存活的对象
再次标记——“stop the world”机制出现短暂的暂停,任务完成整个堆区中存活的对象的标记
清除标记——释放自由的 Region,处理Remembered Set,并发重置空闲的Region块
拷贝——“stop the world”机制出现短暂的暂停,任务将存活的对象复制到未使用过的Region中


五、GC性能评估
1.吞吐量
2.垃圾收集开销
3.暂停时间
4.收集频率
5.堆空间
6.快速


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值