• java垃圾回收


    java垃圾收集

    1. 首先我们来思考一下什么对象是垃圾需要被回收?

      1. 引用计数算法

        每个对象都会有一个整形值用来记录当前他被几个reference类型所持有,当该整型值为0时就表示该对象要被回收。这种回收算法有的明显问题就是存在循环引用的现象,比如A的一个Field是B,B的Filed是A,这样俩个对象就无法被正确判断并回收。

      2. 可达性分析算法

        从GC Root 对象开始所有可以被访问到的都是要被使用的,而剩下的对象就是要被回收的。

        而可以作为GC Root 的对象 包括如下几类:

        • 静态变量
        • 虚拟机中栈所引用的对象。注意:如果对象不存在逃逸的可能使用标量替换在栈上创建,这样效率很高,对象在堆上创建的一个主要原因是为了线程共享,如果不需要)
        • 常量
        • class对象

      当一个对象被标记为死亡时,垃圾回收就会尝试在第一次收集其时尝试调用它的finalize()方法,在这个方法中被回收的对象可以尝试自救,或者通知自己快被回收了。如果这个对象没有重写该方法就直接被回收,如果对象重写了该方法,就会再第二次的该对象被标记为死亡时回收。注意一个对象只有一次自救的机会,即使它第一次自救成功,如果它再次被标记为死亡就不会再调用该方法。

    标记清除算法:

    标记清除算法分为两个阶段:

    1. 标记阶段:

      使用可达性方式并使用深度优先遍历算法,将所有active对象标记为active。

    2. 清除阶段:

      将查看对象是否active不是的话就直接把它分片,并将地址添加到可用内存链表(可用空闲链表)上,这样分配对象,就直接从可用空闲链表上找合适大小的空间并分配。清楚阶段并不会将回收的内存全部置为0,将内存全部置为0应该在创建对象的阶段应该为:刚为对象分配完内存空间之后。

    3. 缺点:

      碎片化问题,对象分配速度

    标记复制算法:

    1. 第一阶段类似:
    2. 不同的是,该收集算法会将内存分为两块,第二阶段会将正在使用的这块内存中未被收集的对象,复制并整齐排列到另一块大小相等的内存。
    3. HotSpot的实现是将新生代分为三块内存,分别为eden,survivor from,survivor to,碧莉为8:1:1,因为标记复制算法在存活对象比较少的时候效率很高,新生代中的对象又比较短命因此比较适合新生代的回收。当对象刚被创建时,分配在eden上(如果eden内存不够就直接分配在老年代),survivor from 中存放上次回收剩下的对象,本次的survivor from 也就是 上次的 survivor to。对象熬过的垃圾回收次数比较多就可能被弄到老年代。
    4. 优缺点:对象存活率低时比较高效,当时空间浪费也是明显的。(降低Survivor 的比例就是在减少空间浪费 )

    标记整理算法:

    标记阶段差不多,但是接下来就要将存活的对象,移向内存一边(紧密排列)

    avatar

    serial:采用串行的方式收集垃圾,会STW。parallelScavenge采用并行的方式收集垃圾但是仍然会STW。parNew,结合CMS和Serial进行收集垃圾。

  • 相关阅读:
    POJ3122贪心或者二分(分蛋糕)
    POJ2118基础矩阵快速幂
    POJ2118基础矩阵快速幂
    POJ1328贪心放雷达
    POJ1328贪心放雷达
    hdu4642博弈(矩阵)
    hdu4642博弈(矩阵)
    POJ1042 贪心钓鱼
    POJ3160强连通+spfa最长路(不错)
    POJ3114强连通+spfa
  • 原文地址:https://www.cnblogs.com/FCY-LearningNotes/p/14799770.html
Copyright © 2020-2023  润新知