zoukankan      html  css  js  c++  java
  • Java 垃圾收集与内存回收

    垃圾收集(Garbage collection, GC)

    收集原理:

    1、引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加一;引用实效,就减一;它的问题是无法解决循环引用。

    2、可达性分析算法:以一系列被称为‘GC Roots’的对象为起点,像下搜索,能到达的对象为可用,否则为不可用。
    GC Roots对象包括:
    虚拟机栈(栈帧中的本地变量表)中引用的对象
    方法区中类静态属性引用的对象。
    方法区中常量引用的对象
    本地方法栈中JNI(即一般说的Native方法)引用的对象。

    finalize方法

    1、如果一个对象没有覆盖finalize方法,当对象被回收打时候,不会执行;
    2、如果有覆盖,但是这个对象之前已经执行过一次这个方法,当对象被回收的时候,也不会执行;
    3、GC时,回收掉一个对象,如果它有覆盖finalize方法,并且之前没有被调用过,并不马上销毁它,而是将它移到F-Quene队列,并又虚拟机启动一个优先级低的Finalizer线程执行它,但是并不保证
    等待它结束。

    GC算法:

    1、标记-清除算法(Mark Sweep):
    先标记不可达队对象,然后统一清除;
    不足是会产生内存碎片;而且效率也不高

    2、复制算法:
    将内存2等分,当一份快用完时,将可达对对象复制到另一份,然后清空当前对象。
    优点是效率高,确定是内存利用率低。

    3、标记整理算法:
    先标记可达的、不可达的对象,然后将可达的内存前移,最后直接清理掉后面的对象。

    4、分代收集算法:
    将内存划分为几块,然后根据每块的特点选择不同的算法。例如:新生代、老年代;

    安全点、安全区域:

    目前所有的GC回收时,都需要暂停用户线程,但是用户线程并不是在每一个地方都能够被GC线程暂停。目前采用的策略是,GC发出一个中断型号,用户线程每在到达安全点点时候,去读这个状态,决定是否
    暂停。
    上述策略解决不了,在中断信号发出之前用户线程已经进入了挂起或者等待状态(此时不在安全点);所以提出安全区点概念;
    安全区:
    指一段区域的代码段,引用不会发生变化。
    线程在进入安全区点时候,会标记自己已经进入了安全区,此时如果发起GC,可以不用理会。如果线程离开安全区时,GC已经完成GC Roots对象的枚举,哪线程继续执行,否则需等待枚举完成。

    收集器:

    1、初生代收集器:
    Serial:单线程的,并且会STOP THE WORLD,STW,即在GC到时候会停止其他用户线程;采用复制算法

    ParNew:多线程的,线程数和CPU数相同,其他和Serial相似;

    Parallel Scavenge:与ParNew 相似,其目标是达到可控的吞吐量(Throughput),吞吐量就是CPU用于用户线程的时间/CPU的总多时间;但是它不关注停顿时间。

    2、老年代收集器:
    Serial Old:Serial 的老年版;同样是采用单线程收集器;采用标记-整理算法;另外一个用途是作为CMS收集器的备案;

    Parallel Old:Parallel Scavenge的老年班;

    CMS(Concurrent Mark Sweep):使用标记-清除算法;以最短回收停顿时间为目标的收集器;将回收分为4各步骤:
    a、初始标记:需要STW用户线程
    b、并发标记:可以和用户线程并发执行,比如有4各用户线程,4个CPU这个时候GC线程也会和用户线程轮流使用CPU。没有阻塞,即为并发。并行指同时运行。
    c、重新标记:需要STW
    d、并发清除:可以并发

    G1收集器:目前在低停顿时间上已经可以和CMS媲美,在低吞吐量上面没有表现的更加优秀。


    总结:目前主流的虚拟机都是使用分代回收的机制;
    1、新生代和老年代可采用不同的收集器,互相配合完成回收任务,虚拟机可以使用参数配置具体采用那种垃圾回收组合
    2、将堆分为新生代和老年代,新生代又分为一个Eden区,2个Survivor区,其中通常Eden / Survivor = 8, 也可以使用参数配置。
    3、通常新生代使用一个Eden、一个Survivor,回收时,将可达对象copy到另外一个Survivor;如果不够,就移动到老年代,如果再不够就启动Full GC,还是不够就OOM
    4、大对象(新生代放不了,或者超过了设置的值)或者长期(4bit,默认15次GC,或者自定义的)存活对象被移入年老代;
    5、android 采用的可能是CMS策略变种。
  • 相关阅读:
    08月24日总结
    08月23日总结
    08月22日总结
    装饰器
    卢菲菲最强大脑记忆训练法全套教程 01
    LeetCode 704 二分查找
    LeetCode 1480 一维数组的动态和
    NIO 总结
    LeetCode 881 救生艇
    url的组成部分
  • 原文地址:https://www.cnblogs.com/lipeil/p/5839173.html
Copyright © 2011-2022 走看看