GC简介

在java中,我们并不需要同使用c/c++一样仔细的管理内存的分配和释放,因为java帮我们实现了内存的回收。垃圾回收(Garbage Collection ,GC)就是java来帮助我们管理内存的回收的。

具体而言,GC主要负责三项任务:分配内存、确保被引用对象的内存不被错误地回收以及回收不在被引用的对象的内存空间
垃圾回收器的存在一方面把开发人员从释放内存的复杂工作中解脱了出来,提高了开发人员的效率;另一方面,GC屏蔽了释放内存的方法,避免了错误的操作内存而导致的应用程序的崩溃,保证了程序的稳定性。但是,垃圾回收也带来了一些问题,为了实现垃圾回收,必定会增加JVM的负担,降低了程序的执行效率。下面简单介绍一下GC的工作原理和使用GC过程中的注意事项。

GC回收的时机

对对象来说,如果没有任何变量去引用他,那么该对象将不可能被程序访问,因此可以认为他是垃圾信息,可以被回收。只有有一个以上的变量去引用该对象,该对象就不会被垃圾回收。
对于垃圾回收器来说,它使用有向图来记录和管理堆内存中所有的对象,通过这个有向图就可以是被哪些对象是“可达的”(有引用变量引用他就是“可达的”),哪些对象是“不可达的”(没有引用变量引用他就是不可达的),所有“不可达“的对象都是可以被垃圾回收的。可以参考实例如下:

    public class Test{
    public static main(String []agrs){
    Integer i1 = new Integer(1);
    Integer i2 = new Integer(2);
    i2 = i1 ;
  }
}

上述代码在执行到i2= i1后,内存引用关系如下图所示。


image.png

此时,如果垃圾回收器赈灾进行垃圾回收操作,在便利上述的有向图时,资源2所占的内存是不可达的,垃圾回收器就会认为这块内存已经不会再被使用了,因此就是回收该块内存空间。

垃圾回收算法

垃圾回收都是依据一定的算法进行的,下面介绍其中集中见长的垃圾回收算法。

引用计算算法(Reference Counting Collector)

引用计数作为一种简单但是效率较低的方法,主要原理如下:在堆中对每个对象都有一个引用计数器;当对象被引用时,引用计数器加1;当引用被置为空或离开作用域时,引用计数减1。由于这种方法无法解决相互引用的问题,因此JVM并没有采用这个算法。

追踪回收算法(Tracing Collector)

追踪回收算法利用JVM维护的对象引用图,从根节点开始便利对象的应用图,同时标记遍历到的对象。当遍历结束后,未被标记的对象就是目前已不被开始使用的对象,可以被回收了。

压缩回收算法(Compacting Collector)

把堆中的活动移动到堆中一端,这样就会在堆中另外一端留下很大的空闲区域,相当于对堆中的碎片进行了预处理。虽然这种方法可以大大简化消除堆碎片的工作,但是每次处理都会带来性能的损失。

负责回收算法(Coping Collector)

把堆分成两个大小相同的区域,在任何时刻,只有其中的一个区域被使用,知道这个区域的被消耗完为止,此时垃圾回收器会终端程序的执行,通过遍历的方式把所有活动的对象复制到另一个区域中,在复制的过程中他们时紧凑的,从而可以消除内存碎片。当复制过程后成勋会接着运行,知道这块区域被试用完。然后在采用上面的方法继续进行垃圾回收。
这个算法的有点时在进行垃圾回收的同时对对象的布置也进行了除了,从而消除了内存碎片,但是这个付出了很高的代价L对于指定大小的堆来说,需要两倍大小的内存空间,同时由于在内存调整的过程中要终端当前执行的程序,从而降低了程序的执行效率。

按代回收算法(Generational Colloector)

把堆分成两个或者多个子堆,每一个子堆被视为一代。算法在运行的过程中优先收集 那些”年幼“的对象,如果一个对象经过多次手机仍然时”存活“的,那么就可以把这个对象转移到高一级的堆里面。减少对其的扫描次数。

手动通知JVM进行垃圾回收

由于立即回收器的存在,java语言本身没有给开发者提供现实释放已分配内存的方法,也就是说,开发人员不能实时的调用垃圾回收器给某个对象进行垃圾回收。但是开发人员却可以通过调用System.gc()方法来”通知“垃圾回收器运行。当然,JVM也并不会保证垃圾回收器马上就会运行,由于System.gc()方法执行会停止所有的响应,去检查内存中是否有可回收的对象。这会对程序的正常运行已经性能造成极大的威胁,因此实际变成的过程中,不推荐频繁的使用这个方法。
当然,finalize()也可以用于释放非 Java 资源,有点类似于C++中的析构函数。但是finalize()方法并一定每次都会调用。我们一般会通过他回收特殊渠道申请的内存。当然,这也得实在GC工作的情况下,如果机器的内存充足,或许永远不会调用到这个方法。

~ 对GC有一个简单的了解之后,我们对内存泄漏的分析和解决 就会比较简单了,下一篇将介绍啊java中的内存泄露和解决方案/。

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

推荐阅读更多精彩内容

  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供...
    简欲明心阅读 89,366评论 17 311
  • 一. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对...
    Stan_Z阅读 1,918评论 0 25
  • 原文阅读 前言 这段时间懈怠了,罪过! 最近看到有同事也开始用上了微信公众号写博客了,挺好的~给他们点赞,这博客我...
    码农戏码阅读 5,946评论 2 31
  • JVM架构 当一个程序启动之前,它的class会被类装载器装入方法区(Permanent区),执行引擎读取方法区的...
    cocohaifang阅读 1,644评论 0 7
  • 1. 垃圾回收的意义在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在...
    爱情小傻蛋阅读 916评论 0 11