Java垃圾回收机制

Java垃圾回收

哪些内存垃圾回收

程序计数器、虚拟栈、本地方法栈3个区域的内存分配都具备确定性,不需要考虑如何回收的问题,当方法结束或线程结束时,内存自然就跟着回收。

垃圾回收针对堆和方法区:这部分区域有很明显的不确定性,只有在运行期间,才能知道程序创建哪些对象、多少对象,这部分内存的分配和回收是动态的。

堆内存回收

判断哪些对象“死亡”(需要回收):

  1. 引用计数法(判断对象的引用数量) 。
  2. 可达性分析法(对象是否引用链可达)。

主流商用程序语言(java,C#)都是通过可达性分析法判断对象是否存活。

原理:通过一系列成为“GC Roots”的根对象作为起始点集,从这写结点开始根据引用关系向下搜索,搜索的路径称作“引用链”,如果某个对象到GC Roots之间不存在任何引用链,则对象不可达,判定此对象不会被再次使用。

另:JDK1.2后对象引用进行了补充:强引用、软引用、弱引用、虚引用,除强引用外其它引用都可能被回收。

执行finalizer()进行内存回收,需要经过两次标记过程。

  1. 第一次标记:可达性分析法判断对象是否存活,对象不可达则被标记,然后进行筛选判断对象是否有必要执行finalizer()(对象未覆盖finalizer(),或finalizer()已经执行过一次都是视为“没有必要执行”),将有必要执行对象放入F-Queue队列。
  2. 第二次标记:放入F-Queue队列对象会被进行第二次小规模标记,若重新与引用链上的对象建立关联,那么会在第二次标记中移除集合,否则将被执行finalizer()进行回收。

方法区内存回收

方法区回收包括两部分:废弃常量,和不再使用的类型

判定一个常量是否废弃:

  • 与对象回收类似,当虚拟机中没有对该常量的引用时将被判定为“废弃常量”,清理出常量池。

判定一个类型不在使用:

  1. 该类所有实例都被释放。
  2. 加载该类的类加载已经被回收。
  3. 该类对应的java.lang.Class对象没有被引用,无法在任何对象通过反射访问该类的方法。

参考

深入理解Java虚拟机(第三版)

你可能感兴趣的:(Java虚拟机,jvm,java)