2018-03-09 GC垃圾回收机制学习日记一

看到Java中的GC垃圾回收机制,必定离不开Java JVM中的内存模型及Java对象的生命周期,学习GC机制前我先简单了解了一下Java的内存模型。

一、Java内存模型

将Java内存简化后,大致分为三个分区:虚拟机栈(线程栈)、Java堆、方法区。

     一、虚拟机栈(VM stack),线程私有,在线程在同一时间创建,管理Java方法执行的内存模型,每个方法执行时都会在对应的线程中的线程栈中创建一个栈帧,这个栈帧主要保存了:局部变量表、操作数栈、动态链接方法,返回地址信息等,当一个方法执行结束后,对应的栈帧中基本类型数据或者对象的引用会被立即释放。栈的大小也代表一个请求对应的最大深度,一个方法中如果存在过多的局部变量,会影响到栈帧的大小,而栈的最大深度也就是线程栈的大小/栈帧的大小,如果请求的深度超过了栈的深度,就会抛出Stack OverflowError异常,这种问题常出现在递归方法,或者大量方法嵌套的环境中。一般栈的大小在线程创建时已经固定,也存在动态扩展的线程栈,但这种方式需注意,当栈进行扩展但是空余的内存不足,无法支持扩展就会抛出OutOfMemoryError异常

(具体的栈帧的描述可以参考:https://www.cnblogs.com/Codenewbie/p/6184898.html

    二、Java堆(Java heap),线程共享,用于存储Java对象实例和数据,GC垃圾回收的主要区域,堆主要分为新生区以及养老区。

        新生区:具体划分为:Eden,Survivor(此处包括两个区域:to survivor,from survivor),用于保存新建的对象(过大的数组创建后会被保存至养老区)及年轻的对象,新建及年轻的对象生灭比较频繁,此处GC采用的回收算法为复制(coping)算法,此处的GC被称为YGC(young GC),也被称为Minor GC,执行速度快。在经过足够多的YGC回收之后,生存时间足够长的对象会被保存至养老区。

        新生区中的Eden space和两个Survivor space(下面简称S0,S1,这两块中会保证一块内存区域为空,另一块保存对象),对象创建时会被存放在Eden中,当YGC触发时,GC会清除不被引用/不可达的对象,然后将Eden和保存对象的survivor区S0中的存活对象,复制保存至S1区域中,清空S0、Eden,然后等下一次YGC触发时,会将Eden、S1的存活对象复制到S0中,经过足够多的YGC后,仍然存活的对象说明对象比较稳定,将对象存至养老区中。

        养老区:用于保存生存时间足够的对象及过大的数据,此处数据的稳定性较强(经过新生区的多次GC,存活的对象说明一直被引用),当养老区内存被完全占用后,会有一次全量的GC,此处的GC采用的回收算法为标记-清除(Mark-Sweep)算法。此处的GC被称为Major GC。

        上面说到了GC回收的两种算法1、复制算法,2、标记-清除-压缩算法,下面会叙述一下两种算法的实现思想及新生区和养老区为何选择两种算法的理由。

        1、标记-清除算法:从根节点gc root根据引用关系来遍历整个堆,并作标记,所有不可达/未被引用的对象上不存在标记,之后回收掉未标记的对象,此处存在两种实现:1:标记-清除,即标记—扫描—清除,这种GC实现会导致内存的不连续,较多的空间碎片会导致内存使用率过低;2、标记-压缩,即标记—扫描—压缩—清除,标记的过程未变,标记完成后,扫描所有的对象,将所有被标记的有效对象压缩至划定的内存的顶部,然后根据有效对象和无效对象的边界,清除所有不可达的对象,不过整理压缩的速度比较慢。

        2、复制算法:首先仍然是标记有效对象的过程,然后将Eden和S0(即当前两块survivor中保存对象的内存区域)中的有效对象,通过复制的方式,移动到S1(即当前为空的survivor区域),然后每次GC都会重复以上的操作,这样处理不会存在内存碎片,但对内存区域结构有对应的要求。

        因为新生区中的对象生灭比较频繁,一次回收可能需要回收掉大部分的对象,当使用标记-清除算法时,会存在内存碎片过多或者是压缩时间过长的问题,而通过复制算法,通过两块survivor区的复制操作,来消除内存中的大量碎片,来降低新生区的GC回收时间。而养老区中大部分对象是经过多次Minor GC回收后存活的对象,此类对象的生灭并不频繁,产生的碎片也较少,整理的代价也比较小。

        关于Major GC、Full GC这两种GC,查阅了一些资料,资料中对于这两种GC的归类存在差异,某些资料中major GC和Full GC被记录在同一个概念中,而一些资料将两者拆分开,这里就不记录了。

     三、方法区,线程共享,线程安全,用于储存class的二进制文件,包括虚拟机加载的类信息、常量、静态变量、即时编译的代码等,又名为Non-Heap(非堆)。

        常量池:方法区中的一块内存,常量的储存位置,在编译期间将一部分的数据保存在该区域,包含基本类型如int、long等以final生命的常量值,和String字符串。

        静态区:方法区内的一块内存,用于存放类中的以static声明的静态成员变量

        Q:在方法中创建变量String demoStr = new String("Test!");说一下这行代码中的信息保存在JVM的那些区域?

        A:首先String demoStr这个局部变量名(保存了内存地址)会被保存到虚拟机栈中的方法栈帧中的局部变量表,而通过new String(),创建的String对象会在堆中被创建,栈帧中保存的地址指向对堆内对应对象,而具体代码的信息则在方法区。若是新建局部变量为基本类型如int,此局部变量的值也会被保存在栈帧中。当方法结束时,栈帧会立刻释放栈帧中对堆中对象的引用。

注:每次GC操作都是STW(Stop-The-World)操作,即除了GC回收的线程,其他所有线程都处在等待阶段,如果最大STW过大会造成程序停顿

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