zoukankan      html  css  js  c++  java
  • Java对象的生与死

    读书笔记:《深入理解Java虚拟机》第三章

    回收的区域:
         垃圾收集重点关注的区域是方法区和堆,因为只有这两个区域使用不可预估。而栈、程序计数器等因为是线程私有,方法调用进栈出栈有条不紊。

    引用计数法:
         在对象中添加一个引用计数器,当被引用的时候,计数器加一,当计数器为0的时候,表示对象没有引用,这是一个常规、简单、高效的方法,但是这种方式难以解决相互循环引用的问题(即A、B对象中有变量互相引用对方对象。)

    可达性分析算法:
         主流商用语言均使用的算法,基本思想是如果对象有“GC ROOTS”相关联的引用链,进行可达性分析,如果不可达表示当前对象与GC ROOTS没有了引用链。

    由此,可以作为GC ROOTS对象的有:

    • 栈中引用的对象
    • 方法区中静态类属性引用的对象
    • 方法区中常量引用的对象
    • 本地方法栈引用的对象(JNI)

    java的引用类型:

    • 强引用类型
      • 强引用类型是new出来的,所以虚拟机即使抛出内存溢出错误,也不会回收这部分内存。
    • 软引用类型
      • 软引用属于可以回收但是弃之可惜的,所以只有当即将内存溢出的时候,然后回收这部分对象,如果还是依然不够,那就抛出异常。
    • 弱引用类型
      • 弱引用只能存活到下一次垃圾收集之前。
    • 虚引用类型
      • 一个对象设置虚引用类型的唯一目的是收到一条系统回收的通知。

    对象被回收的两次标记过程:
         经过上面,我们已经知道,不可达对象就表示此对象没有了引用链,那么他们会成为垃圾收集器的目标,此时他们会被标记一次!!!但是并不是被回收,而是被判“缓刑”,真正宣判对象完蛋至少经历2次标记过程

         第一次被标记并进行一次筛选,筛选的条件就是是否有必要执行finalize()方法,没有必要执行的前提是该对象没有覆盖finalize()方法或者系统执行过此方法,那么,如果有必要执行就会将此对象放入一个F-queue的队列,等待一个叫Finalizer的低级线程执行finalize方法,此时finalize方法是一个对象逃脱回收的最后机会!GC会在队列中进行小规模的第二次标记,如果对象没有在finalize方法中自救(与可作为GC Roots的对象发生关联的话),就会真正被回收。

    方法区回收:
    废弃常量无用的类,这是这方法区回收被关注的地方!

    废弃的常量是指没有被其他任何对象引用,比如“abc”,没有String对象引用到它这个字面量,那么它就需要移除常量池

    无用的类,满足三个条件才能成为无用的类:

    • 中再也没有该类的任何实例
    • 该类的ClassLoader被回收
    • 该类对应的java.lang.Class对象没有被引用到,无法通过反射进行访问该类方法
  • 相关阅读:
    linux中的find命令——查找文件名
    int main(int argc,char* argv[])详解
    VIM进阶学习之几种模式和按键映射
    Fortran编译多个文件(转载)
    Vimdiff---VIM的比较和合并工具
    两篇很牛的vim使用技巧
    程序员软件的罪恶:从不清楚地汇报事故原因
    Free symbol is Harmful
    return语言结构 VS. scala默认返回值
    踩过的“坑”: 命令行指定Java class path
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608393.html
Copyright © 2011-2022 走看看