深入理解JAVA虚拟机笔记 - 02

来源:互联网 发布:北京黑马程序员地址 编辑:程序博客网 时间:2024/06/05 00:32

垃圾收集器篇之垃圾确定方法

java自带垃圾收集功能,动态控制内存,废话少说,进入正题
首先明确 垃圾回收回收的实哪部分的内存:“程序计数器,虚拟机栈、本地方法栈3个区域的随线程而生,随线程而灭;栈中的栈帧随着方法的进入和退出执行进栈出栈,每一个栈帧中分配多少内存基本是在类结构确定下来时就已知的,因此这几个区域的分配和回收都具有确定性,不需要过多考虑。而Java堆和方法区就不一样了,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期间才能知道会创建哪些对象,这部分的存的分配”和回收都是动态的,垃圾收集器所关注的就是这部分内存–《深入理解JAVA虚拟机》“。ok,抄了书上一段原话,说到底嘛,既然JAVA是动态的进行内存的分配与回收,那么它所能够分配和回收的内存应该也是动态的(个人理解)。要进行”垃圾回收“,首先要确定哪些是”垃圾“,先介绍一些确定对象状态的基本方法

对象回收

  • 引用计数法
    给对象添加一个引用计数器,每当有一个地方引用它时,计数器加1,每当一个引用失效时,计数器减1,任何时刻当计数器为0对象就是不可能被引用的,实现简单,判定效率高,但有一个很大的问题就是无法解决对象之间互相引用的问题
  • 可达性分析算法
    通过一系列被称为GC Roots的对象作为起始点,从这些节点向下搜索,搜索所走过的路径成为引用链,当一个对象到GC Roots 没有任何引用链相连,则证明此对象是不可用的(GC Roots(虚拟机栈(栈帧中的本地变量表,方法区中的静态属性引用对象,方法区中常量引用的对象,本地方法栈中JNI引用的对象))
  • 引用
    强引用:程序代码中普遍存在的,A a = new A();只要强引用存在,垃圾收集器永不回收该对象;
    软引用:有用但是非必须的对象,在一般时候不会回收,当要放生内存溢出异常的时候才会对这些对象进行回收,如果回收之后内存还不够,才会跑出内存溢出异常
    弱引用:同样是来描述非必须对象,但是要弱于软引用,弱引用的对象只能存活到下一次垃圾收集之前
    虚引用:不会对对象产生任何影响,唯一的目的就是这个对象被回收的时候收到一个系统通知(此处不是很理解,应该大概就是对象被回收了,虚引用发出一个通知说该对象被回收了)
  • 生存还是死亡(书上小节原话)
    在可达性分析中被判定为不可达的对象并不是非得被回收,它们还有一次”修改“自己的机会。真正宣告一个对象死亡至少要经历两次标记过程,当一个对象被判定为不可达之后,会被第一次标记,并执行一次筛选,筛选的条件是该对象是否需要执行finalize()方法(当对象没有覆盖该方法或该方法已被执行过),如果判定为有必要执行finalize方法,则会给其一个执行的机会,如果执行完毕还是没有引用,基本上可以被回收了

方法回收

很多人认为方法区(永久代)没有垃圾收集,但是事实上是可以进行垃圾回收的,主要回收废弃常量和无用的类
废弃常量:一个字符串进入了常量吹但是没有任何一个String对象引用该常量,也没有其他地方引用了这个字面量
无用的类:
- 该类的所有实例都已被回收,Java堆中不存在该类的任何实例
- 加载该类的ClassLoader已被回收
- 该类对应的Java.lang.Class对象没有在任何地方被引用,无法再任何地方通过反射访问该类的方法
虚拟机可以对废弃changlhe无用的类进行回收,并不是必然回收

0 0
原创粉丝点击