zoukankan      html  css  js  c++  java
  • 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进行收集垃圾。

  • 相关阅读:
    用一个测试类简化排序算法时间复杂度的研究
    用斗地主的实例学会使用java Collections工具类
    数据结构:用实例分析ArrayList与LinkedList的读写性能
    用一个通俗易懂的例子彻底说清楚单例模式
    用自定义链式栈解决力扣括号匹配问题
    数据结构之链式队列的代码实现及有趣应用
    用非常硬核的JAVA序列化手段实现对象流的持久化保存
    SpringBoot整合SpringSecurity实现JWT认证
    六百字搞懂lambda
    判空我推荐StringUtils.isBlank
  • 原文地址:https://www.cnblogs.com/FCY-LearningNotes/p/14799770.html
Copyright © 2011-2022 走看看