Java 垃圾回收机制(一)
一、垃圾回收集 (GC)
- java 内存运行时区域的程序计数器、虚拟栈、本地方法 3 个区域随线程生,随线程亡。而 java 堆和方法区有着不确定性,需要动态的内存分配和回收。
二、引用计数算法 (Reference Counting)
- 算法原理:在对象中添加引用计数器,被引用时计数器值加一,当引用失效时计数器值减一。当对象的引用计数器值为 0 时,对象不能再被利用了。
- 算法缺陷:在两个对象互相引用对方时,会导致它们的计数器值不为 0 ,从而引用计数算法不能够回收它们。
三、可达性分析算法 (Reachability Analysis)
- 算法原理:通过一系列“GC Roots”的根对象(起始结点),根据引用关系向下搜索,搜索过程经过的路径为“引用链”(Reference Chain)。如果某个对象与 GC Roots 没有相连的引用链,就说明该对象是不可达的,就是不会再被利用。
- Java 中固定作为 GC Roots 的对象:
- 在虚拟机栈中引用的对象。如方法栈中用到的参数、局部变量、临时变量等。
- 在方法区中类静态属性引用的对象。
- 在方法区中常量引用的对象。
- 在本地方法栈中 JNI (Native 方法) 引用的对象。
- Java 虚拟机内部的引用。如基本数据类型对应的 Class 对象。
- 所有被同步锁(synchronized 关键字)持有的对象。
- 反射 Java 虚拟机内部情况的 JVMBean、JVMTI 中注册的回调、本地代码。
四、引用类型
- 强引用 (Strongly Reference)
- 传统的引用定义,指在代码中普遍存在的引用赋值。重要存在强引用,垃圾回收器就不会回收被引用对象。
- 软引用 (Soft Reference)
- 描述有用但非必须的对象。对于被软引用关联的对象,系统发生内存溢出前,会被进入第二次回收范围,如果内存还不够,才会抛出内存溢出异常。
- 弱引用 (Weak Reference)
- 描述非必要对象,相比于软引用更弱。对于被弱引用关联的对象,只能生存到下一次垃圾收集发生为止。垃圾收集器开始工作时,无论内存够不够都会被回收。
- 虚引用 (Phantom Reference)
- 也称为“幽灵引用”或者“幻影引用”,最弱的引用关系。对象设置虚引用的唯一目的是为了在对象被垃圾收集器回收时收到一个系统通知。
五、对象的生与死
- 在可达性分析算法中一个对象的死亡至少分为两个阶段:
- 在可达性分析中进行分析是否与 GC Roots 有引用链。如果没有则进行第一次标记。
- 判断对象是否必要执行 finalize() 方法。如果有必要则对象会被放置到 F-Queue 队列中,由虚拟机自动建立的、地调度优先级的 Finalize 线程去执行 finalize()。反之没有必要执行,例如,对象没有覆盖 finalze(),或者 finalize() 已经被虚拟机执行了。
六、回收方法区
- 方法区的垃圾收集主要分为:①废旧的常量。②不再使用的类型。其中判断废旧常量相对简单,后面一个相对复杂。
- 满足“不再使用类型“三个条件:
- 该类的所有实例都已经被回收。
- 加载该类的类加载器已经被回收。
- 该类对应的 java.lang.Class 对象没有被引用。
最后
- 计划整理面试题的第一篇,后续会陆续整理到一个专栏里面。の呃呃呃呃呃