探索java回收机制

一、垃圾回收机制的意义
垃圾回收机制可以有效的防止内存的泄漏,有效的使用空闲的内存。
内存泄漏: 是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,java的内存泄漏表现为一个内存对象的生命周期超出了程序需要的它的时间长度。
垃圾回收功能:
(1) 定期发现那些对象不再被引用,并把这些对象占据的堆空间释放出来。
(2) 类似于操作系统的内存管理,垃圾收集器还需要处理由于对象动态生成与撤销产生的堆碎块,以便更有效的利用虚拟机内存。
虽然说,Java语言规范没有明确说明JVM使用哪种垃圾回收算法,但是任何一种垃圾回收算法一般要做两件事情:(1) 发现无用的信息对象 (2) 回收将无用对象占用的内存空间。使该空间可被程序再次使用。

二、对象存活判断
1. 引用计数算法
1.1 算法分析:
堆中每一个对象都有衣蛾引用计数。当新创建一个对象,或者有变量被赋值为这个对象的引用,则这个对象的引用计数加1;当一个对象的引用超过生存期或者被设置一个新的值时,这个对象的引用计数减1。当对象的引用计数变为0时,就可以被当作垃圾收集。
这种方法的好处是垃圾收集较快,适用于实时环境。缺点是这种方法无法检测出循环引用。例如对象A引用对象B,对象B也引用对象A,则这两个对象可能无法被垃圾收集器收集。
1.2 优缺点
优点: 引用计数收集器可以很快的执行,交织在程序运行中,对程序需要不被长时间打断的实时环境比较有利。
缺点:无法检测循环引用。如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,它们的引用计数永远不可能为0.
1.3 引用计数器无法解决循环引用问题,例如:
这里写图片描述
最后的两句是将Objtect1 和 Object2 赋值为 NULL,也就是说 Objtect1 和 Object2 指向的对象已经不可能再被访问,但是由于它们相互引用对方,导致它们的引用计数器都不为0,那么垃圾收集器永远不会回收它们。
2. 可达性分析算法
将“GC Roots”算法对象作为起始节点,向下搜索,搜索走过的路径为引用链;当一个对象到GC Roots 没有引用链时,则该对象时不可用的;
可作为“GC Roots”的对象:
(1)方法区中静态属性引用的对象
(2)方法区中常量引用的对象
(3)虚拟机栈引用的对象(装祯中本地变量表)
(4)本地方法栈中JNI引用的对象(Native)
三、 垃圾回收算法
1. 标记-清除算法
定义:先标记要回收的对象,然后统一回收。
适用:存活对象较多的垃圾回收。
缺点:
(1)效率低;标记和清除的过程效率不高;
(2)空间问题;标记清除后产生大量不连续的内存碎片,给大对象分配内存时没有足够连续的内存空间,导致提前触发垃圾回收动作。
这里写图片描述
2. 复制算法
定义:将可用内存划分成相等大小的两块,每次只使用其中一块,当这一块用完后将还存活的对象复制到另一块。然后将已使用过的内存一次清理。
适用:存活对象较少的垃圾回收。
优点:每次对整个半区进行内存回收,不用考虑内存碎片问题,只要移动堆顶置针,按顺序分配内存即可;实现简单,运行高效。
缺点:将内存缩小了一半。
3. 标记-整理算法
定义:先标记要回收的对象,将存活对象移动至另一端,最后清理端边界以外的内存。
这里写图片描述

4.  分代收集算法
    定义:根据对象存活周期将内存划分为新生代和老年代,然后根据每个年代的特点使用合适的回收算法。
    如:新生代存活对象少可以采用复制算法;老年代存活对象多并且分配担保必须使用标记清理或标记整理回收算法。

四、垃圾回收器
这里写图片描述
1. Serial 收集器
定义:单线程收集器,收集时必须暂停其他所有用户线程,直到收集结束。
适用:新生代
配置:
-xx:PretenureSizeThreadshold
-XX:HandlePromotionFailure
其他:
(1)单CPU环境Serial收集器没有现成交互开销,因此单线程的收集效率高。
(2)对于Client模式下的桌面应用,分配给虚拟机的内存不会很大,对于一两百兆的新生代内存回收停顿时间完全控制在一百多毫秒以内,停顿不频繁发生,Serial收集器时最好的选择。
(3)收集过程会暂停服务(Stop the world)
这里写图片描述
2. ParNew收集器
定义:是Serial 收集器的多线程版本
适用:新生代
配置:
-XX:PretenureSizeThreshold
  -XX:HandlePromotionFailure
-XX:+UseConcMarkSweepGC (设置默认新生代收集器)
 -XX:+UserParNewGC (指定ParNew作为新生代收集器)
-XX:ParallelGCThreads(限制垃圾收集的线程数)
其他:
(1)与Serial 收集器的控制参数,收集算法,Stop the world ,对象分配规则,回收策略完全一样。
(2)是运行Server模式下虚拟机首选新生代收集器(唯一能和CMS收集器配合的规则)
CMS 是兵法收集器,第一次实现让收集线程和用户线程同时工作;
CMS关注回收的停顿时间(暂停用户线程时间),停顿时间越短越适合于用户交互的程序,因为有较高的响应速度
(3)单CPU环境没有Serial 收集器效率高
(4)并行的多线程收集器
这里写图片描述
3, Parallel Scavenge 收集器
定义:和ParNew收集器一样的收集器,区别在于主要关注吞吐量的控制和GC自适应调节策略;
注:吞吐量 = 运行用户代码时间/(运行用户代码时间+垃圾收集时间); 如果虚拟机总共运行100分钟,收集花费1分钟,则吞吐量为99%
适用: 新生代;较高的吞吐量,导致高效的CPU利用率,主要适合后台运算
配置:
-XX:MaxGCPauseMillis (控制回收停顿的最大时间 ; 注:时间越小会牺牲吞吐量和新生代空间)
  -XX:GCTimeRatio (设置吞吐量 0< X < 100 ; 垃圾回收时间占总时间的比例, 吞吐量的倒数);如果将GCTimeRatio设置为19,最大GC时间占总时间的5%(即1/(1+19));该值默认为99,则最大GC时间为1%    
-XX:+UseAdaptiveSizePolicy (打开GC自适应调节策略) 
其中: GC自适应调节策略:虚拟机根据当前系统性能,自动调节参数已提供最合适的时间和最大吞吐量;
调节的参数包括: (i)新生代大小(-Xmm),Eden 和 Survivor 空间比例(-xx:SurivivorRatio)
(ii)晋升老年代对象的年龄(-xx:PretenureSizeThreshold)
GC自适应调节策略将内存管理交给虚拟机完成,只需要设置基本内存(-Xmx),停顿时间(MaxGCPauseMillis),吞吐量(GCTimeRatio)等参数给虚拟机设立优化目标;
其他:
(1)并行:多条垃圾回收线程并行关注,单用户线程处于等待状态
并法:用户线程和回收线程同时进行
(2)并行的多线程收集器
这里写图片描述
4. Serial Old收集器
定义:是Serial 收集器的老年代版本的单线程收集器
适用:老年代(标记-整理算法);主要给Client模式下的虚拟机使用;

  1. Parallel Old收集器
    定义:是Parallel Scavenge收集器的老年代版本的多线程收集器
    使用:老年代(标记-整理算法)
    6.CMS收集器(COncurrent Mark Sweep)
    定义:CMS是一款兵法收集,低停顿的收集器。
    关注目标:最短回收停顿时间。
    适用:互联网站,B/S系统服务端(较快的响应速度,最短的系统停顿时间)较好的用户体验
    算法:标记-清除
    回收步骤:
    (1)初始标记(标记GC Roots能直接关联到的对象)(Stop the world)
    (2)兵法标记(进行GC Roots Tracing的过程)
    (3)重新标记(修正并发期间因用户程序继续运行而导致标记产生的对象的标记记录)(stop the world)
    (4)并发清除
    执行时间:
    T(并发标记,并发清除)> T(重新标记) > T(初始标记)
    由于耗时最长的并发标记和并发清除和用户线程一起工作,因此总体上CMS回收过程和用户线程一起并发执行的。

  2. G1 收集器
    定义:一款面向服务端应用的垃圾收集器
    算法:标记-整理
    特点:
    (1)并行与并发
    充分利用多CPU,多核环境缩短Stop the world 停顿时间,使用并发方式回收避免了GC时停顿Java线程
    (2)分代收集
    (3)空间整合(使用标记-整理 回收算法,避免了大量空间回收碎片的产生)
    (4)可预测的停顿(G1在追求低停顿同时建立了可预测的停顿时间模型,可以让使用者设置M毫秒内,GC所需要的时间不超过N毫秒)
    原理:
    1. G1 将新生代和老年代 分为大小相等的独立区域,进行全区域垃圾回收,新生代和老年代不再是物理隔离,都是部分独立区域的集合;
    2. 通过计算每个区域垃圾堆积的价值(回收可得到的空间/回收所需要的时间),然后根据价值大小有优先级的进行垃圾回收,保证了回收的效率。‘
    3. 虚拟机发现独立区域中的Reference类型数据进行写操作时,判断其他独立区域是否有Reference数据引用的对象(即老年代对象是否引用了新生代对象),如果是就将引用信息通过CardTable记录到独立区域的Remembered Set中,在垃圾回收的时候将Remembered Set加入到GC根节点的枚举范围,可避免使用可达性算法判断对象存活而进行的全堆扫描,也避免有存活对象的遗漏。
    回收步骤:
     【1】初始标记(标记GC Roots能直接关联到的对象,并修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确的Region中创建对象)(Stop the World)
     【2】并发标记(从GC Roots开始对堆中对象可达性分析,找出存活对象)(和用户线程并发进行)
    【3】最终标记(修正并发标记期间因用户线程运行的而产生变动对象的标记记录,虚拟机将这些对象记录到Remembered Set Logs中,然后合并到Rembered Set中)(Stop the World)
     【4】筛选回收(对每个独立区域进行价值排序,根据用户期望的GC停顿时间制定回收计划)
    这里写图片描述

五、回收器的组合使用
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值