JVM内存模型(三)--- 垃圾收集算法

Java的技术体系包括

  • 支持Java程序运行的虚拟机(JVM)
  • 提供接口支持的Java API
  • Java 编程语言
  • 第三方Java框架(如Spring等)

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人想出来。


我们知道,Java虚拟机运行时的内存分为:程序计数器,虚拟机栈,本地方法栈,堆,方法区几个部分。其中程序计数器,虚拟机栈,本地方法栈3个区域与线程相关,生命周期与线程同步。栈中的栈帧,随着方法的进入和退出而进行着入栈出栈的工作,每个方法需要分配多少内存在编译期间也已经确定下来,所以当方法结束时,内存也跟随着回收。因此这几个区域不需要考虑内存回收的问题,他们会随着线程结束或者方法结束而有条不紊的进行内存的释放。

而堆和方法区则不同,由于只有在程序运行期间才能知道会创建哪些对象,同时每个对象的大小,生命周期等也不尽相同,所以导致这部分内存的分配和回收都是动态的,因此垃圾收集所关注的重点区域就是这部分内存。我们所说的垃圾回收算法和内存分配策略绝大多数都是围绕堆内存展开。

如何判断一个对象需要被垃圾回收

可达性分析算法

Java主流实现中,都是通过可达性分析算法来判断对象是否需要被回收。算法的基本思路是,通过一系列被称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots之间没有任何引用链的时候,则证明此对象可以被回收。

其中GC Roots包括如下几种

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

引用类型

Java中有值类型和引用类型两种。其中引用类型被定义为:如果reference类型的数据中存储的数值代表另一块内存的起始地址,就称这块内存代表着一个引用。在JDK1.2以后,Java对引用的概念进行了扩充,分为强引用软引用弱引用虚引用

  • 强引用,new 出来的引用,默认的引用方式。如果有强引用存在,对象不会被回收
  • 软引用,SoftReference,在虚拟机内存不足的时候,会回收掉这些对象
  • 弱引用,WeakReference,被弱引用关联的对象,只能存活到下一次垃圾回收之前。换句话说,如果一个对象只有弱引用,那么当垃圾回收扫描到这个对象时,它将被回收
  • 虚引用,PhantomReference

方法区的内存回收

在虚拟机规范中指出,方法区可以不要求实现垃圾回收。而且方法区的回收效率一般都比较低。在堆中尤其是新生代中,常规的一次垃圾回收,一般可以回收掉70%~95%的空间。但实际上很多虚拟机都实现了在方法区的内存回收,因为在需要大量使用反射,动态代理,CGLib等ByteCode框架,等频繁自定义ClassLoader的场景,是需要具备类卸载的功能,以保证方法区不会溢出。

方法区的内存回收主要分为两部分,废弃常量无用的类

  1. 回收废弃常量与回收Java堆中的对象类似,即没有任何对象引用常量池中的常量时,被回收。该常量可以包括字符串常量,类引用等。
  2. 无用的类,判定条件需同时满足以下3个条件
    • 该类的所有实例都已经被回收。也就是堆中不存在该类的任何实例
    • 加载该类的ClassLoader已经被回收
    • 该类对应的java.lang.class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法

虚拟机可以对满足以上3点的类进行回收,但是否真的回收,可以通过虚拟机提供的参数进行控制。

垃圾回收算法

Java虚拟机中主流的垃圾回收算法分为以下几种

  1. 标记清除算法。算法分为标记、清除两个阶段。首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。这中算法是所有算法的基础,后续算法均是对其不足进行改造而得到的。它的不足主要体现在两方面
    • 效率问题,标记和清除的效率都不高
    • 空间问题,标记清除之后会产生大量的不连续内存碎片,这就导致在需要分配较大内存空间的时候,如果此时没有连续的足够大的内存空间,则需要提前进行下一次垃圾回收行为,这会造成资源的浪费和效率的降低。
jvm标记清除算法
  1. 复制算法。为了解决效率问题而产生。它将可用内存分为两部分,每次只使用其中的一块,当这一块内存用完之后,就将还存活的对象复制到另一块上面,然后再把刚才已使用的一块内存空间一次性清理掉即可。高效体现在两个方面
    • 每次只对其中一块内存进行回收
    • 内存分配时不需要考虑碎片问题,只需要移动堆顶指针按顺序分配即可。极大的提升了效率。
jvm复制算法.png

这种算法被用来实现在虚拟机的新生代中。并且分为三部分,Eden占80%,两块Survivor各占10%。每次使用Eden和其中的一块Survivor,当回收时,将Eden和Survivor中还存活的对象一次性复制到另一款Survivor中。最后清理掉Eden和刚才用过的Survivor空间。

  1. 标记整理算法,主要用于老年代的算法。它首先标记处所有需要回收的对象,然后让所有
    存活的对象都向一端移动,再直接清理掉端边界以外的内存。
jvm标记整理算法.png
  1. 分代收集算法,根据对象的存活周期不同,将内存划分为几块。一般是将堆分为新生代和老年代。这样可以根据各个年代的特点采用最适当的收集算法。
    • 在新生代中,每次垃圾回收都会有大量对象死去,少量存活,因此可以采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集
    • 在老年代中,因为对象存活率高,没有额外空间进行分配担保,可以采用标记整理算法进行回收

在虚拟机通过可达性分析算法寻找需要回收的对象的时候,首先就是需要找到GC Roots,那么如何高效实现对GC Roots的查找(即如何发起内存回收),是虚拟机在具体实现过程中需要首先解决的问题,以HosSpot虚拟机为例,通过OopMap-安全点-安全区域的一套机制来快速准确的完成对GC Roots的枚举。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容