JVM垃圾回收机制

一、java垃圾回收机制的存在意义

C++的程序员在new出来一个新的对象时,其实是一个很痛苦的事,因为程序员需要对这个对象的生死存亡负起重要的责任,当一个对象在使用完之后,如果没有及时释放,那么就会造成严重的内存泄漏问题。java在引入了垃圾回收机制后,意在让java程序员可以不用去对这些对象负责,在不需要的时候,可以由java的垃圾回收线程去回收这些对象,避免内存泄漏。那么问题来了,我们是否可以任意的创建对象,然后不去理会后续处理,单纯的依赖gc呢?这是后话

二 jvm是如何判断一个对象可以被GC回收的

jvm判断一个对象是不是可以回收,最核心的判断就是:这个对象有没有被有效引用。jvm现在提供两种核心算法来判断一个对象是否处于可回收状态,分别是:
1 引用计数法
引用计数法简单来说,就是jvm在每个对象的实例中都有一个引用计数,当这个对象被创建,并且被一个变量所引用的时候,那么就讲这个引用计数+1,当这个对象实例的某个引用超过了生命周期或者被设置为一个新值时,这个对象的引用计数就减1。那么当jvm的gv启动的时候,就会回收所有少于1的对象。
引用计数法可以很快的执行gc,不会长时间的中断程序的执行,但是这会带来一个经典的问题:对象相互引用的问题。出现循环引用的对象,采用引用计数法,是不会被gc所回收的。
2 根搜索算法
jvm把所有的对象的引用关系看成一张图,也就是说从GCRoot开始,寻找对应的引用节点,然后找到这些引用节点的下一个引用节点,经过遍历之后,没有被GCRoot所引用的节点,都会被回收。

根搜索算法可以很好的解决循环引用不能被回收的bug
java中可以被当成GCRoot的对象有:
1 方法区中的静态属性引用的对象
2 方法区中常量引用的对象
3 虚拟机栈和本地方法栈引用的对象

三 jvm的垃圾回收算法

在上面我们知道了,jvm是如何判断一个对象时可以被回收的,那么,接下来jvm是如何在内存中操作这些可回收对象的呢?jvm为我们提供了一下几种垃圾回收算法:
1 标记清除法
jvm从根开始扫描对象,对存活的对象进行标记,标记完毕后,jvm会在次执行,把没有被标记的变量进行回收。标记清除法不需要对对象进行移动,在存活对象比较多的情况下,还是很高效的,但是这种算法会带来一个严重的问题:内存碎片过多。
2 复制算法
复制算法的核心思想是在内存中划分两个区域,如果一个区域中的内存用完之后,就把这个内存中的可达对象复制到另一块内存区域中,然后再回收当前的内存,这种好处就是可以极大的避免内存碎片过多,但是这样会造成内存的浪费,因为每次都需要划分多余的内存区域进行GC回收处理
在现代的虚拟机中,使用复制算法进行新生代的垃圾回收实现。在现代的虚拟机中,我们一般把内存分为三个区域,分别是一块比较大的Eden区域和两块比较小的Survivor区域。当e区和一块S区内存满时,GC开始回收,把e区和s区的可达对象集中起来放到另一块S区中。
如果S区的内存不够存储当前的可达对象是,那么就需要借助老年代内存区的帮忙了
3 标记整理算法
标记整理算法比较适合于老生代的内存区域。因为在这个内存区域中,可达对象比较多,如果采用复制算法,那么算法的效率就会比较低
标记整理算法的核心思想就是,在GC到来时,把内存区域中的所有可达对象向一端移动,然后清除端边界意外的内存。
4 分代回收算法
虚拟机把内存分为三个模块,分别是新生代,老生代,永久代。新生代由于存活对象比较少,所以可以采用复制算法,老生代可达对象比价多,GC触发不频繁,所以比较适合标记整理算法,永久代理论上不存在不可活状态,所以GC不会再这个内存区域触发。永久代现在的虚拟机已经废弃了
hotspot虚拟机认为,发生在新生代的对象存活,一次gc过后,只能存在最多10%的存活对象,因此,在新生代的划分可以分为一个eden区+两个survivor区。其中eden和survivor的内存大小是8:1。当jvm往新生代分配对象的时候,一般是先往eden区中分配内存。由上面我们知道,新生代一次gc过后,存活的对象都比较少,所以采用复制算法,一来可以提高速度,避免内存随便产生。二来可以将存活的对象分配到另一个survivor中。如果survivor被分配满了,那么剩余的对象就会被分配到老生代中。

其它补充

Minor GC:Minor GC也即是发生在新生代的gc,在新生代的内存堆中,GC会频繁的发生,在这个过程中,一般采用复制算法,避免大量的内存碎片的发生。
Full GC指发生在老年代的 GC,出现了 Major GC,经常
会伴随至少一次的 Minor GC。MajorGC 的速度一般会比 Minor GC 慢 10 倍以上。

虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在 Eden 出生并经过第一次 Minor GC 后仍然存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为 1。对象在 Survivor 区中每熬过一次 Minor GC,年龄就增加 1 岁,当它的年龄增加到一定程度(默认为 15 岁)时,就会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。

一个对象是不是一定要等到年龄的阀值>=15的时候,才会被分配到老年代中?
答案是:否。在survivor区中,如果相对对象的年龄的内存总和大于当前survivor的一半,那么大于当前对象年龄的对象都会被移动到老年代中。

一个对象如果被置为null,是不是会被马上回收??
这个问题存在两个陷阱。
1 gc是不是发现对象为null的时候,就马上回收?并不是,gc线程是jvm自己控制运行的一个独立的线程,我们只能建议jvm马上调用gc算法,至于系统是否响应,就要看jvm自己的调度情况
2 一个对象为null,是不是gc执行的时候,一定会被回收?答案是否。gc在判断一个对象是不是需要被立马回收,回去判断这个对像的finalize()方法是否被重写。如果在finalize()方法中,我们重新将这个对象指向另一个对象,那么,gc也就不会去回收这个对象了。但是,finalize()系统只会去判断一次。如果我们再一次置空,那么,这个对象就会被gc回收掉。

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

推荐阅读更多精彩内容