垃圾收集器和内存分配

来源:互联网 发布:淘宝网男士短袖 编辑:程序博客网 时间:2024/06/13 21:14
垃圾收集器和内存分配
1.新生代串行回收期:
    a.最古老的垃圾回收器,也是JDK中最基本的垃圾回收器之一
    b.特点:
        1.仅仅使用单线程进行垃圾回收
        2.独占式的垃圾回收
    c.串行收集器进行垃圾回收时,java应用程序中的线程都需要暂停,等待垃圾回收完成。
      该操作会导致长时间的 STW ,如果在实时性要求较高的应用场景中,会造成糟糕的用户体验。
    d.成熟高效的回收器,大多情况下其性能表现还是相当不错的.
    e.使用的是复制算法,实现相对简单,逻辑处理特别高效,且没有线程切换的开销
    f.使用-XX:+UserSerialGC 参数指定使用新生代串行收集器和老年代串行收集器,当虚拟机
       在client 模式下运行,他是默认的垃圾收集器

2.老年代串行回收期:
    a.特点:
        1.仅仅使用单线程进行垃圾回收
        2.独占式的垃圾回收
    b.老年代垃圾回收通常会比新生代的回收需要更长的时间,因此,一旦老年代垃圾回收启动,
       应用程序可能会因此停顿较长的时间
    c.和多种新生代回收器配合使用,也可以作为CMS 回收器的备用回收器
    e.启用老年代垃圾回收器
        1.-XX:+UseSerialGC   新生代,老年代都使用串行回收期
        2.-XX:+UseParNewGC   新生代使用 ParNew 回收器,老年代使用串行回收器
        3.-XX:+UseParallelGC 新生代使用 Parallel 回收器,老年代使用串行回收器

3.新生代的ParNew回收器:
    a.工作在新生代的垃圾收集器,只是简单的将串行回收器多线程花,回收策略,算法以及参数和
       新生代串行回收器一样
    b.也是独占式的回收器。由于使用了多线程进行垃圾回收,在并发能力较强的 cpu 上,产生的 stw 要短
      但是在单 cpu 或者并发能力较弱的系统中,并行的效果还不如串行。根据不同的cpu选择不同的回收器
    c.开启 ParNew 回收器
        1.-XX:+UseParNewGC          新生代使用 ParNew 回收器,老年代使用串行回收器
        2.-XX:+UseConcMarkSweeoGC   新生代使用 ParNew 回收器,老年代使用 CMS
        3.-XX:+ParallelGCThreads    指定ParNew 工作时的线程数,最好与cpu数量相当

4.新生代 ParallelGC回收器:
    a.使用复制算法的收集器,和ParNew 一样都是多线程,独占式收集器,但是 ParallelGC 非常关注系统的吞吐量
    b.开启ParallelGC 回收器
        1.-XX:+UseParallelGC       新生代使用 ParallelGC 回收器,老年代使用串行回收器
        2.-XX:+UseParallelOldGC    新生代使用 ParallelGC 回收器,老年代使用 ParallelOld 回收器
    c.关注系统吞吐量的两个重要参数
        1.-XX:MaxGCPauseMillis     设置最大垃圾收集时间,它是一个大于0的整数,Parallel 工作时,
                       会调整java堆栈的大小或者其他参数,尽可能的把时间控制在
                       MaxGCPauseMillis 以内。不宜把时间设置的太小,这样会增加垃圾回收
                       的次数,降低了吞吐量
        2.-XX:GCTimeRatio       设置吞吐量的大小,是一个0到100之间的整数,默认是 19
        3.-XX:+UseAdaptiveSizePolicy    打开自适应 GC 策略,新生代的大小、Eden和survive的比例、晋升老年代的
                        对象年龄等参数会自动调整以达到在堆大小、吞吐量和停顿时间之间的平衡点
                        在手工调优比较困难的场合,可以直接使用这个方式
    d.GCTimeRatio 和 MaxGCPauseMillis  两个参数的互相矛盾的,减少一次收集的最大停顿时间,就会减少系统吞吐量
                       增加系统的吞吐量又可能同时增一次垃圾回收的最大停顿
5.老年代的 ParallelOldGC 回收器:
    a.ParallelOldGC 回收器也是一种多线程并发的回收器,和新生代 ParallelGC 回收器一样,它也是一种关注吞吐量
      的收集器,使用标记压缩算法,它在 JDK1.6 中才可以使用
    b.开启 ParallelOldGC 回收器
        1.-XX:+UseParallelOldGC    新生代使用 ParallelGC 回收器,老年代使用 ParallelOld 回收器
        2.-XX:+ParallelGCThreads    指定ParNew 工作时的线程数

6.CMS回收器:
    a.工作步骤【初始标记】-->【并发标记】-->【预清理】-->【重新标记】-->【并发清理】-->【并发重置】
    b.CMS 不是独占式的回收器,所有应用程序仍然会不停的工作,就会不断地产生垃圾,新产生的垃圾在当前的
      CMS 是无法清除的,为了保证应用程序的运行,当堆内存使用率达到一定的阈值时便会开始进行回收
    c.主要参数设置
        1.-XX:UseConcMarkSweepGC    启动 CMS 参数
        2.-XX:ConnGCThreads        设定并发线程数
        3.-XX:ParallelGCThreads        设定并发线程数
        4.-XX:CMSInitiatingOccupanyFraction  指定回收的阈值,默认是 68(针对老年代)
        5.-XX:+UseCMSCompactAtFullCollection 垃圾收集完成之后进行一次内存碎片清理
        6.-XX:CMSFullGCCsBeforeCompaction    设定多少次 CMS 后,进行一次内存压缩
        7.-XX:CMSClassUnloadingEnabled         指定 CMS 可以回收 Perm 区

7.G1回收器:
    a.G1回收器是JDK1.7中正式使用的全新的垃圾回收器,属于分代垃圾回收器,但是不要求新生代或者
      老年代连续
    b.特点
        1.并行性:多个GC同时工作
        2.并发性:与应用程序交替执行
        3.分代GC:分代回收器,兼顾新生代和老年代
        4.空间整理:回收过程中,会进行适当的对象移动,减少空间碎片
        5.可预见性:因为分区的原因可以只选取部分区域进行内存回收
    c.内存划分:将堆进行分区,划分一个个区域,每次收集值收集其中的几个区域,从而达到控制GC回收产生的停顿时间
    d.收集过程
        新生代GC:
        并发标记周期:
            1.初始标记
            2.根据区域扫描
            3.并发标记
            4.重新标记
            5.独占清理
            6.并发清理
        混合标记:
        必要的FullGC:回收过程内存不充足,转入 Full GC
    e.相关的参数
        1.-XX:+UseG1GC        启用G1收集器
        2.-XX:MaxGCPauseMillis    指定最大的停顿时间
        3.-XX:ParallelGCThreads    指定并行回收时,GC 工作的线程数量
        4.-XX:InitiatingHeapOccupancyPercent    指定当堆内存使用率达到多少时触发GC,默认值是 45

8.对象内存分配和回收的一些细节
    1.禁用 Sysytem.gc() ,会显示的调用 Full GC。一般情况下无需搜定触发GC,系统自动进行即可
    2.Sysytem.gc()使用并发回收,忽视UseG1GC 和 UseConcMarkSweepGC 参数
    3.并行 GC 前额外出发的新生代 GC
    4.对象如何进入老年代
        初创的对象在 eden 区
        老年对象进入老年代
        大对象进入老年代
    5.在TLAB 上分配对象
    6.finalize()对垃圾回收的影响
        在finalize()时可能导致对象复活
        finalize()执行时间是没有保障的
        糟糕的 finalize() 会严重影响 GC 的性能