必知必会JVM垃圾回收——对象搜索算法与回收算法

垃圾回收(GC)是JVM的一大杀器,它使程序员可以更高效地专注于程序的开发设计,而不用过多地考虑对象的创建销毁等操作。但是这并不是说程序员不需要了解GC。GC只是Java编程中一项自动化工具,任何一个工具都有它适用的范围,当超出它的范围的时候,可能它将不是那么自动,而是需要人工去了解与适应地适用。

拥有一定工作年限的程序员,在工作期间肯定会经常碰到像内存溢出、内存泄露、高并发的场景。这时候在应对这些问题或场景时,如果对GC不了解,很可能会成为个人的发展瓶颈。

接下来的两文将详细学习下JVM中垃圾回收(GC)的各个知识要点。本文先从GC的算法开始先了解,铺垫好基础,下一篇再详细讲JVM具体的GC实现。

GC对象搜索算法

垃圾回收,第一件事就是要搞清楚哪些东西是垃圾,而后才能对这些垃圾进行回收。

那么有什么办法识别对象是否为无用的垃圾呢?狭义地,怎么判断对象是否没被引用呢?

通常有以下两种算法去识别判断

  • 引用计数算法
    这个算法非常简单。给对象一个计数器,每当这个对象被引用了,计数器值加一;引用失效,则减一。但这个对象计数值为0的时候,证明是无用对象,可以被GC程序回收掉。这种算法比较广泛应用在一些脚本语言上,如FLASH、PYTHON等。
    但是引用计数算法无法解决对象间相互引用的问题。当a对象引用了b对象,b对象也引用了a对象,这样a、b两个对象的计数器值都不会为0,即使这两个对象都被其他对象所引用,最终导致这些对象一直无法被回收。这种情况往往会出现在比较复杂的编程语言中。

  • 可达性分析算法
    可达性分析算法(GC roots算法),广泛应用于主流的商用语言。设置一个根节点,从图论角度来看,只要从该节点可达一个对象,证明这个对象是存活的(被引用)。

通常地,GC会包含以下区域的对象:

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

垃圾回收算法

了解完垃圾是怎么找出来后,接下来看看它们是怎么被清除的。以下介绍几种清除的算法。

标记-清除算法(Mark-Sweep)

标记-清除,顾名思义,先标记垃圾,再清除。它是GC最基础的算法,后续很多算法都是基于它上面去改进的。
标记的过程在上面搜索GC对象已经介绍过了。被标记的对象,在统一GC的时候会把标记的对象清除掉。这个算法比较简单,不做过多赘述。


这个算法有一个很明显的缺点,就是在垃圾回收后会产生大量不连续的碎片空间,导致程序要申请较大的对象时常无法找到合适的内存空间,迫使再次GC。

复制算法

复制算法的存在,正是为了解决内存碎片问题。并且这个算法也是分代算法的基础。

将内存分为大小相等的两块,每次程序只使用其中一块,当GC发生的时候,把存活的对象复制到另外一块内存中,整齐的排列,然后清空原来的那块内存。



可以看到,这种算法有点新生代转移到老年代的感觉。

缺点:

  1. 把内存可使用的空间减少了一半,造成空间的浪费。
  2. 对象存活数量较多的时候,复制性能比较差

这种缺点,在老年代中,对象存活率比较高的场景下是非常场景间。

标记-整理算法(Mark-Compact)

针对复制算法的两个缺点,在老年代一般会用这种标记-整理算法。

把存活的对象移到内存的一段,然后把剩余的空间全部清空掉。


分代收集算法

分代算法并不是一个特定的算法,也没有什么新的内容。而是把内存分成多个区域,一般为新生代、老年代等。然后根据不同区域不同的特点,用不同回收算法去回收垃圾。

例如新生代,对象存活率低,比较适用复制算法。老年代存活率高,比较适用Mark-Compact算法。

目前几乎所有的商业虚拟机都是采用分代收集的。具体不同的收集器在下一文再详细说明。


更多技术文章、精彩干货,请关注
博客:zackku.com
微信公众号:Zack说码

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

推荐阅读更多精彩内容

  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供...
    简欲明心阅读 89,337评论 17 311
  • jvm原理 Java虚拟机是整个java平台的基石,是java技术实现硬件无关和操作系统无关的关键环节,是java...
    AI乔治阅读 17,208评论 21 486
  • JVM架构 当一个程序启动之前,它的class会被类装载器装入方法区(Permanent区),执行引擎读取方法区的...
    cocohaifang阅读 1,630评论 0 7
  • 一. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对...
    Stan_Z阅读 1,916评论 0 25
  • 最近一次无比认真,无比热情和我交流的异性是谁? 是我领导的儿子,今年十岁,和我讨论订书机的原理,撬锁的原理,讨论成...
    芷妹妹阅读 382评论 0 1