Java虚拟机(四)--垃圾回收

垃圾回收

java基于内存的动态分配,回收也是自动且动态回收。
因java程序计数器、虚拟机栈、本地方法栈均伴随线程产生而产生,线程销毁而销毁。栈帧的内存基本是类加载后肯定的,大多不考虑这部分的内存回收。
而java堆以及方法区不一样的是,咱们只有在运行时才能知道会建立哪些对象,这部份内存是动态分配的,于是采用动态回收机制。java

分类

一、引用计数算法

给对象添加一个引用计数器,当对象被一个地方引用,则计数器加一;当引用失效时,计数器减一。当计数器为0时,对象为不可用,须要被清除。
缺点是两个相互引用的对象,虽然对象已无其它引用,可是也不能被清除,GC没法回收它们算法

二、可达性分析算法

使用GC roots 对象做为起点,从该节点向下搜索的路径称为引用链。当对象与GC roots之间没有任何引用链相连时,该对象为不可用。线程

能够做为GC roots 对象的几种状况:对象

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

引用的分类,该4中分类中引用的强弱递减

一、强引用

是经过new 产生的对象,即Object obj = new Object(),该引用类型引用的对象永远不会被回收。内存

二、软引用

用于描述非必须但有用的对象,在可能发生内存溢出以前,会将对象列入回收范围。虚拟机

三、弱引用

用于描述非必需的对象,在下次垃圾回收时,无论内存是否足够,均会清除该类对象。效率

四、虚引用

最弱的一种引用,没法经过虚引用获取一个对象。垃圾回收

垃圾回收算法

一、标记清除算法
标记清除算法指“标记”和"清除”两个过程,首先对须要回收的对象进行标记,在标记后同一回收全部被标记的对象。
这种算法会产生大量的碎片,致使须要分配较大内存时,不得不提早出发下一次垃圾回收,而且标记和清除两个过程效率较低。搜索

二、复制算法
为了解决标记清除算法引出的缺点,复制算法得以出现。
复制算法首先将内存一分为二,每次只用一块,当一块用完了,将还须要使用的对象复制到另外一块,而后对已使用的内存进行清理。
这样使得内存可用范围缩小了一半。
目前主流的虚拟机,通常讲内存分为三部分 80%的Eden和两个较小占10%的survivor区,这样分布是基于新生代98%的对象都要回收,因此每次只浪费10%的survivor区域,若是某次回收的对象超过10%,须要依赖其它内存分配担保。引用

三、标记整理算法

当有对象存活率较高时,进行复制操做,效率会下降。针对老年代提出了另外一种算法:“标记整理”。
顾名思义,咱们先对须要清除的对象进行标记,而后对对象进行整理,使全部对象向一端移动,而后清除边界之外的内存。

四、分代收集算法

目前商业主流虚拟机均采用该类算法,根据对象存活周期将内存区域分为几块,在新生代中,对象更新较快,于是选用复制算法。老年代中,对象回收率较高,于是采用“标记-清除”或“标记-整理”算法进行回收。

相关文章
相关标签/搜索