• Java GC


    GC需要的内存区域

    我们的内存垃圾回收主要集中于 java 方法区中,在程序运行期间,这部分内存的分配和使用都是动态的

    Minor GC

    从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC

    触发

    • 当Eden区满时,触发Minor GC

    Full GC

    清理整个堆空间—包括年轻代和永久代

    触发

    • 调用System.gc时,系统建议执行Full GC,但是不必然执行
    • 老年代空间不足
    • 方法去空间不足
    • 通过Minor GC后进入老年代的平均大小大于老年代的可用内存

    判断对象可回收

    • 引用计数

    每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题

    • 可达性分析

    从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。不可达对象。

    GC Roots包括:

    • 虚拟机栈中引用的对象
    • 方法区中类静态属性实体引用的对象
    • 方法区中常量引用的对象
    • 本地方法栈中JNI引用的对象

    GC算法

    标记清除

    为每个对象存储一个标记位,记录对象的状态(活着或是死亡)。分为两个阶段,一个是标记阶段,这个阶段内,为每个对象更新标记位,检查对象是否死亡;第二个阶段是清除阶段,该阶段对死亡的对象进行清除,执行 GC 操作

    优点

    • 不需要额外空间
    • 每个活着的对象的引用只需要找到一个即可,找到一个就可以判断它为活的

    缺点

    • 产生过多的内存碎片
    • 效率低(每个活着的对象都要在标记阶段遍历一遍)

    标记压缩

    标记清除算法的改进版。同样,在标记阶段,该算法也将所有对象标记为存活和死亡两种状态;不同的是,在第二个阶段,该算法并没有直接对死亡的对象进行清理,而是将所有存活的对象整理一下,放到另一处空间,然后把剩下的所有对象全部清除。这样就达到了标记-整理的目的

    优点

    • 该算法不会像标记-清除算法那样产生大量的碎片空间
      缺点
    • 如果存活的对象过多,整理阶段将会执行较多复制操作,导致算法效率降低

    复制算法

    该算法将内存平均分成两部分,然后每次只使用其中的一部分,当这部分内存满的时候,将内存中所有存活的对象复制到另一个内存中,然后将之前的内存清空,只使用这部分内存,循环下去。

    注意:
    这个算法与标记压缩算法的区别在于,该算法不是在同一个区域复制,而是将所有存活的对象复制到另一个区域内

    优点

    • 简单,不会产生内存碎片
      缺点
    • 每次GC时都会有一半内存是空的,浪费空间

    分代收集算法

    现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生代(Young)和老年代(Tenure)。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担保,所以可以使用标记-整理 或者 标记-清除

    具体过程
    新生代(Young)分为Eden区,From区与To区

    当系统创建一个对象的时候,总是在Eden区操作,当这个区满了,那么就会触发一次YoungGC,也就是年轻代的垃圾回收。一般来说这时候不是所有的对象都没用了,所以就会把还能用的对象复制到From区

    这样整个Eden区就被清理干净了,可以继续创建新的对象,当Eden区再次被用完,就再触发一次YoungGC,然后呢,注意,这个时候跟刚才稍稍有点区别。这次触发YoungGC后,会将Eden区与From区还在被使用的对象复制到To区

    再下一次YoungGC的时候,则是将Eden区与To区中的还在被使用的对象复制到From区

    经过若干次YoungGC后,有些对象在From与To之间来回游荡,这时候From区与To区亮出了底线(阈值),这些家伙要是到现在还没挂掉,对不起,一起滚到(复制)老年代吧

    老年代经过这么几次折腾,也就扛不住了(空间被用完),好,那就来次集体大扫除(Full GC),也就是全量回收。如果Full GC使用太频繁的话,无疑会对系统性能产生很大的影响。所以要合理设置年轻代与老年代的大小,尽量减少Full GC的操作

    收集器

    转自
    https://blog.csdn.net/laomo_bible/article/details/83112622

  • 相关阅读:
    js对url进行编码和解码(三种方式区别)
    node.js之nodemon 代码热更新 修改代码后服务器自动重启
    深刻理解this的指向和var 定义的变量的问题
    js数组遍历some、foreach、map、filter、every、lastIndexOf、indexOf对比
    div左边固定宽度,右边自适应宽度
    div 自适应高度 自动填充剩余高度
    子组件通过 $emit 触发父组件的自定义事件
    js导出带格式的表格(包括单元格合并,字体样式等)
    vue在生产环境清除console.log
    js判断设备是都是pc端
  • 原文地址:https://www.cnblogs.com/xiongyungang/p/13657999.html
Copyright © 2020-2023  润新知