1. 哪些内存需要GC
    • 判断对象是否还存活

      • 引用计数法

        • 给对象中添加一个引用计数器,每当一个地方引用它时,计数器值就加1;当引用失效时,计数器的值就减1,任何时候计数器为0的对象就是不可能再被使用的。
        • 微软公司的COM技术,使用ActionScript3的FlashPlayer等都使用了引用计数算法来进行内存管理。
        • 但是Java虚拟机里面没有选用引用计数算法来管理内存,其中最主要的原因时它很难解决对象之间相互循环引用的问题
      • 可达性分析算法:
        • 在主流的商用程序语言(Java, C#, Lisp等)都是通过可达性分析算法来判断对象是否存活的。
        • 通过一些“GC Roots” 的对象作为起始点,从这些结点开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象时不可用的。
        • Java中可作为GC Roots 的对象包括:
          • 虚拟机栈(栈中的本地变量表) 中引用的对象
          • 方法区中类静态属性引用的对象
          • 方法区中常量引用的对象
          • 本地方法栈中JNI(一般说的Native方法)引用的对象
      • 在可达性分析算法中不可达的对象,仍有机会“自救”。一个对象真正被判断死亡,至少要经历两次标记过程。
        • 在可达性分析算法后发现没有与GC Roots 相连接的引用链,将会第一次被标记并且进行一次筛选,条件为是否有必要执行finalize()方法。
        • 如果对象没有覆盖这个方法,或者已经被虚拟机调用过了,则视为没有必要执行
        • 自救:只要在finalize()方法中重新与引用链上的任何一个对象建立关联即可

  2.什么时候进行GC

    • 可达性分析过程中必须保证一致性,也就是指在分析过程中,对象的引用关系不能发生改变,导致GC进行时,必须停顿所有Java执行线程。
    • 而当执行系统停顿下来之后,并不需要一个不漏地检查完所有执行上下文和全局的引用位置。使用一组称为OopMap的数据结构来记录哪些地方存放着对象引用。
    • 在类加载完成的时候,HotSpot就把对象内什么偏移量上是什么类型的数据计算出来,在JIT编译过程中,也会在特定的位置记录下栈和寄存器中哪些位置是引用。
    • 并不是什么地方都能停顿下来进行GC,只有到达安全点时才能暂停,那么如何让所有线程都到了最近的安全点再停顿下来呢?

      • 抢先式中断:不需要线程的执行代码主动配合,GC发生时,首先中断全部线程,再恢复不在安全点上的线程,让它跑到安全点上。
      • 主动式中断:当GC需要中断线程时,不直接对线程操作,而是仅仅简单设置一个标志,各个线程执行时,主动去轮询这个标志,发现标志为真时就主动中断挂起,而轮询标志的地方是与安全点重合的。
    • 安全点机制

      • 但是如果为每一条指令都生成对应的OopMap,那将会需要大量的额外空间,这样GC的空间成本将会变得很高。
      • 因此设置一个安全点机制,只有在达到安全点时才能暂停。既不能太少以致于让GC等待时间太长,也不能太过于频繁以至于过分增大运行时的负荷.
    • 安全区域机制
      • 使用安全点机制似乎已经完美解决了如何进入GC的问题,但是这个机制能保证程序执行时,在不太长的时间内就会遇到可进入GC的安全点,但是程序不执行的时候呢
      • 这个时候,就需要安全区域来解决了。安全区域是指在一段代码片段中,引用关系不会发生改变。在这个区域中的任意地方开始GC都是安全的。

  3.如何进行GC

    • 标记-清除算法

      • 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象
      • 不足:
        • 效率问题,标记和清除两个过程的效率都不高,
        • 空间问题:标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作
    • 复制算法
      • 将可用内存容量划分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完后,就将还存活者的对象复制到另一块上面,然后把已使用过的内存空间一次清理掉。
      • 这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针。按顺序分配内存即可,实现简单,运行高效。
      • 问题:代价是将内存缩小为了原来的一半
      • 改进:
        • 目前商业虚拟机都采用这种收集算法来回收新生代,而研究表明,新生代中的对象98%是“朝生夕死”的,所以并不需要1:1的比例来划分。而是将内存分为一块较大的Eden空间和两块较小的Survivor空间。
        • 当回收时,将Eden和Survivor中还存活着的对象一次性地复制到另外一块Survivor空间上,最后清理Eden和刚才用过的Survivor空间
        • 这样只有10%的内存会被“浪费”
        • 当然当出现Survivor空间不够用时,需要依赖其他内存(这里只老年代)进行分配担保
    • 标记-整理算法
      • 标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
    • 分代收集算法
      • 根据对象存活周期的不同将内存划分为几块,一般是将java堆分为新生代和老年代,这样就可以根据每个年代的特点采用最适当的收集算法。
      • 在新生代中,每次垃圾收集都会有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。
      • 而老年代因为对象的存活率较高,且没有额外空间对它进行担保,就必须使用标记-清除或者标记-整理算法来进行回收

GC的过程的更多相关文章

  1. 源码分析HotSpot GC过程(二):DefNewGeneration的GC过程

    由于虚拟机的分代实现,虚拟机不会考虑各个内存代如何实现垃圾回收,具体的工作(对象内存的分配也是一样)由各内存代根据垃圾回收策略自行实现. DefNewGeneration的使用复制算法进行回收.复制算 ...

  2. 不得不知的CLR中的GC

    引言 GC 作为CLR的垃圾回收器,让程序员可以把更多的关注度放在业务上而不是垃圾回收(内存回收)上.其实很多语言也有类似的东东, 如Java也有JIT 等等 GC基本概念 垃圾回收机制的算法有好多种 ...

  3. 《代码的未来》读书笔记:内存管理与GC那点事儿

    一.内存是有限的 近年来,我们的电脑内存都有好几个GB,也许你的电脑是4G,他的电脑是8G,公司服务器内存是32G或者64G.但是,无论内存容量有多大,总归不是无限的.实际上,随着内存容量的增加,软件 ...

  4. 触发Full GC执行的情况

    除直接调用System.gc外,触发Full GC执行的情况有如下四种. 1. 旧生代空间不足 旧生代空间只有在新生代对象转入及创建为大对象.大数组时才会出现不足的现象,当执行Full GC后空间仍然 ...

  5. C#的GC机制(来自网摘复制,未整理)

    第一个就是很多人用.Net写程序,会谈到托管这个概念.那么.Net所指的资源托管到底是什么意思,是相对于所有资源,还是只限于某一方面资源?很多人对此不是很了解,其实.Net所指的托管只是针对内存这一个 ...

  6. Android GC 那点事

    版权声明:本文由陈昱全原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/170 来源:腾云阁 https://www.qclo ...

  7. 如何避免后台IO高负载造成的长时间JVM GC停顿(转)

    译者著:其实本文的中心意思非常简单,没有耐心的读者建议直接拉到最后看结论部分,有兴趣的读者可以详细阅读一下. 原文发表于Linkedin Engineering,作者 Zhenyun Zhuang是L ...

  8. GC学习笔记

    GC学习笔记 这是我公司同事的GC学习笔记,写得蛮详细的,由浅入深,循序渐进,让人一看就懂,特转到这里. 一.GC特性以及各种GC的选择 1.垃圾回收器的特性 2.对垃圾回收器的选择 2.1 连续 V ...

  9. GC之三--GC 触发Full GC执行的情况及应对策略

    1.System.gc()方法的调用 此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发 Full GC,从而增加Full GC的频率,也即增加了间歇性停顿的次数. ...

随机推荐

  1. install kali on my x200

    1 下载kali镜像,选择tsinghua tuna mirror https://mirrors.tuna.tsinghua.edu.cn/kali-images/current/ 选择light版 ...

  2. jmeter 报错Error in NonGUIDriver java.lang.IllegalArgumentException: Report generation requires csv output format, check 'jmeter.save.saveservice.output_format' property

    设置jmeter报个的时候报下面错 只要细心看问题就是把它jmeter.save.saveservice.output_format'的格式改为csv就对 这个属性是在jmeter.propertie ...

  3. 影响Arcmap运行效率的因素

    在使用ArcMap的过程中,总觉得ArcMap运行起来非常慢,目前发现了两点原因: 一.渲染太多图斑 比较常见的,我们在打开矢量图层时,Arcmap会自动渲染加载进去的图斑,进行符号化.在渲染的过程中 ...

  4. linux btrfs文件系统管理与应用

    btrfs文件系统管理与应用 1.btrfs文件系统 基本介绍 btrfs文件系统在CentOS7.x上属于技术预览版 btrfs文件系统英文名:B-tree  FileSystem或者Butter ...

  5. rem 自适应适配方法

    rem是指相对于根元素(html)的字体大小的单位,它是一个相对单位,它是css3新增加的一个单位属性,我们现在有很多人用的都是px,但px是一个绝对单位,遇到分辨率不同的设备,做出的页面可能会乱,这 ...

  6. 通过sql查找指定字段存在哪些表中

    select * from INFORMATION_SCHEMA.columns where COLUMN_NAME Like '%order_type%';

  7. 输入框VS软键盘

    最近在做一个h5的时候遇到的问题 我们都知道当页面上的有输入框被选中了,这个时候就回调出键盘用户可以输入.但是安卓手机在弹出键盘时页面的输入框也会被覆盖住: 以下为暂时的解决办法:(以下方法同时解决了 ...

  8. 设置table的每竖的宽度

  9. vue day6 分页显示

    @{ ViewBag.Title = "Home Page"; Layout = null; } <!DOCTYPE html> <html> <he ...

  10. UE4 材质编辑

    1.颜色反转(纹理颜色白变黑,黑变白)