• 深入理解JVM 垃圾收集


    1. 概述

    垃圾收集器 Garbage Collection。
    垃圾收集器需要完成的三件事

    • 哪些内存需要回收
    • 什么时候回收
    • 如何回收

    只有Java堆和方法区需要考虑内存回收,程序计数器、虚拟机栈、本地方法栈的内存分配和回收都具有确定性。

    2. 如何判断对象已死

    1. 引用计数法 Reference Counting

    在对象中添加一个引用计数器,每当被其他对象引用,计数器+1,引用失效则计数器-1,当计数器值为0时表名该对象不可能再被使用。
    原理简单、判定效率高,难以解决循环引用问题。

    2. 可达性分析算法 Reachability Analysis

    通过一系列称之为 GC Roots 的根对象作为起始集,从这些根对象开始,根据引用链关系向下搜索,搜索过程走过的路径称之为引用链 Reference Chain,如果某个对象到GC Roots间没有引用链相连,也即从GC Roots到这个对象不可达,则证明该对象不可再被使用。

    GC Roots

    1. 虚拟机栈(栈帧中的局部变量表)中引用的对象,如参数、局部变量、临时变量等。
    2. 本地方法栈中Native方法引用的对象
    3. 方法区中类静态属性引用的对象,如Java类的引用型静态字段
    4. 方法区中常量引用的对象,如字符串常量池中的引用
    5. VM内部引用,如基本数据类型对应的Class对象,常驻异常对象(NPE、OOM),系统类加载器等
    6. 同步锁/监视器锁 synchronized 所持有的对象
    7. 反应 JVM 内部情况 JMXBean、JVMTI 中注册的回调、本地代码缓存等。

    以上是固定 GC Roots,根据用户选择的垃圾收集器及当前回收的内存区域不同,还可以有其他临时性对象加入。如分代收集和局部回收(Partial GC),针对局部剧区域的回收,还需要考虑该区域内对象被其他区域对象引用。当然为了避免 GC Roots 的膨胀,都进行了各种优化处理。

    3. 各种引用

    强软弱虚四种引用。
    强引用 Stringly Reference:最传统的引用,只要还可达,就不会被回收。
    软引用 Soft Reference:OOM前对这些引用进行回收,若内存还不足才会OOM。SoftReference 类
    弱引用 Weak Reference:只能生存到下一次 GC。WeakReference 类。
    虚引用 Phantom Reference:虚引用的存在不影响对象本身的生存时间,只是在对象被回收时得到通知。PhantomReference 类。

    4. 标记过程

    要宣告一个对象 不可达,至少需要经历两次标记。
    第一次判断不可达,判断 finalize 方法是否已重写或是否已被 VM 调用过。若没有,则放入 F-Queue 队列,由 VM 自动建立的,低优先级的 Finalizer 线程执行 finalize 方法。
    第二次对F-Queue对象判断是否可达,若不可达则此对象宣告死亡。

    finalize 释放资源的问题:执行时间不确定,若某对象 fianlize 执行缓慢甚至死循环,可能导致内存回收子系统的崩溃。

    当对象不可达时,可在 finalize 中拯救自己一次。

    5. 方法区回收

    主要两部分内容:废弃的常量和不再使用的内存。
    类不再使用

    • 实例全部已被回收
    • 加载该类的类加载器已被回收
    • 该类的 Class 对象没有被引用
      -Xnoclassgc、-verbose:class、-XX:+TraceClassLoading、-XX:+TraceClassUnLoading
  • 相关阅读:
    【项目】项目225
    【原创】如何带格式转载博客园文章或其他网站的文章
    【项目】项目226
    【项目】项目229
    【项目】项目223
    【项目】项目230
    【项目】项目227
    如何带格式转载博客园文章或其他网站的文章
    Thread.Sleep(0)真的是bug吗?
    14.redis的慢日志
  • 原文地址:https://www.cnblogs.com/chenxingyang/p/16146735.html
Copyright © 2020-2023  润新知