Java虚拟机笔记 jvm notes(II GC)

垃圾回收机制

比较好的文章:


1⃣️可回收对象算法

  • 目前查看对象是否需要回收的算法主要由两种:引用计数法可达性分析
  • 引用计数虽好,但是无法解决对象之间相互循环引用但是实际上这些对象没什么卵用时造成的内存泄漏;

  • java采用的是可达性分析算法(Reachability Analysis)来判断对象是否存活:从GC Roots出发,可以到达的对象就是存活的,到达不了的就要被GC;

  • GC Roots可以是虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区中类静态属性引用的对象、方法区中产量引用的对象、本地方法栈引用的对象;这些对象的特点就是不被GC管理(GC回收的是堆上对象,GC roots位于方法区、虚拟机栈和本地方法栈),可以作为GC Roots的对象见可以作为GC Roots的对象

  • 一个对象真正的死亡需要两次被标记的过程:如果对象在进行可达性分析后没有发现和GC Roots相连的引用链,将会被第一次标记并进行一次筛选,筛选条件是此对象是否需要执行finalize()方法,当对象没有重写覆盖finalize()方法或者finalize()方法已经执行过一次,则虚拟机认为不需要执行finalize()
    如果虚拟机认为需要执行finalize(),则会将对象放入F-Queue队列中,等待Finalizer线程执行触发finalize()方法。在这个队列等待过程中,如果重新和引用链上的对象发生关联(重新引用),第二次标记的时候将会移除“等待回收”的对象集合,这个对象就重新存活了。若没有,将会被第二次标记然后被回收。

  • 引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference),这四种强度逐渐减弱。


四种引用介绍:

  1. 强应用:就是我们代码中最常见的引用方式,GC在强引用对象可达时不会回收;
  2. 软引用:使用java.lang.ref.SoftReference来创建软引用,软引用的特点是当内存不足时,GC会将其回收;适合作为缓存使用
  3. 弱引用:使用java.lang.ref.WeakReference来创建弱引用,特点是每次GC都会将其回收,无论内存充足与否;
  4. 虚引用:使用java.lang.ref.PhantomReference来创建虚引用,其特点是和引用它的对象生命周期无关,GC任何情况下都会回收它。虚引用仅用来处理资源的清理问题,比Object里面的finalize机制更灵活。get方法返回的永远是null,Java虚拟机不负责清理虚引用,但是它会把虚引用放到引用队列里面。
    使用:对于软引用和弱引用,可以有两种构造方式:使用ReferenceQueue引用队列或者不使用ReferenceQueue,例如:
WeakReference<String> wr = new WeakReference<String>(str);

或者

ReferenceQueue<String> rq = new ReferenceQueue<String>();
WeakReference<String> wr = new WeakReference<String>(str, rq);

软引用和弱引用很相似,也是最常用的非强引用,
而对于虚引用PhantomReference只能配合ReferenceQueue使用:

ReferenceQueue<String> rq = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(str, rq);


2⃣️垃圾收集算法

  • 当对象判断为可回收后,需要专门的算法去执行回收动作。垃圾收集算法主要分为以下几种:
  • 标记-清除算法,Mark-Sweep:顾名思义,缺点是效率慢,容易造成内存碎片;
  • 复制算法,Coping:将内存空间分为几块区域,每次只使用其中一块E,当一块快用完了,就将存活的对象复制到另外一块S上,然后把使用的E一次性清除干净。实际上这种算法用于新生代的垃圾回收,E即Eden,S就是Survivor,缺点是Survivor空间不够时需要老年代内存来担保,即所谓的分配担保(Handle Promoting);
  • 标记整理算法,Mark-Compact:和标记-清除算法的区别在于,标记后并不直接进行清理,而是将存活对象向内存空间的一端移动,然后直接清除存活边界以外的内存空间,避免碎片化;
  • 分代收集算法,Generational Collection:实际上就是上述垃圾收集算法的组合,即在不同的内存区域采用不同的收集算法。比如在新生代采用复制算法,在老年代采用标记-整理/清理算法。
  • 在Hotspot中使用一组称为OopMap的数据结构来达到这个目的,在类加载完毕的时候,HotSpot就会把对象内什么偏移量上是什么类型的数据计算出来。在JIT中也会在特定的位置记录下栈和寄存器的引用的位置。
  • HotSpot并非为每条指令都生成OopMap,只在安全点SafePoint记录。即程序执行到安全点才暂停下来开始GC。
  • 收集器的性能指标:
    1⃣️吞吐率(1 - GC总时间/总时间):高吞吐量能提高CPU效率,适合交互较少的程序;
    2⃣️最大暂停时间:越短越适合交互比较多的程序;
    3⃣️堆空间使用率:
  • 常见的收集器:
  1. Serial:单线程收集器,新生代运行,使用复制算法,在安全点暂停所有线程开始GC;
  2. ParNew:多线程版本的Serial,新生代运行;优先配合CMS
  3. Parallel Scavenge:新生代收集器,使用复制算法,可以控制吞吐量,吞吐量优先收集器;配合Serial Old使用,不能搭配CMS;
  4. Serial Old:Serial的老年代版本,老年代运行,使用标记-整理算法;
  5. Parallel Old:Parallel Scavenge的老年代版本,优先考虑配合Parallel Scavenge;
  6. CMS:Concurrent Mark Sweep,获取最短暂停时间,老年代运行;
  7. G1:Garbage First,最新的收集器,老年代和新生代都可以使用。
GC 描述 适用年代 VM参数 偏重 搭配
Serial 单线程收集器 新生代 -XX:+UseSerialGC 单核CPU VM参数下同时启动Serial Old
ParNew 多线程收集器 新生代 -XX:+UseConcMarkSweepGC或-XX:+UseParNewGC 多核CPU CMS
Parallel Scavenge 并行多线程 新生代 -XX:+UseParallelGC 吞吐量 VM参数下默认Serial Old
Serial Old Serial的老年代版本 老年代 -XX:+UseSerialGC CMS的替补 Parallel Scavenge(jdk1.5以前)
Parallel Old Parallel Scavenge的老年代版本 老年代 -XX:-UseParallelOldGC 吞吐量/CPU资源 Parallel Scavenge
CMS Concurrent Mark Sweep 老年代 -XX:+UseConcMarkSweepGC 暂停时间 -XX:+UseConcMarkSweepGC同时启动ParNew
G1 优先搜集占用空间大的垃圾 全局 -XX:+UseG1GC 在暂停时间内尽可能收集多内存 全局使用
  • jdk 7默认的GC回收器组合是ParNew + CMS;

  • 一个典型的32位JVM,Java堆大小设置在2 GB(使用分代&并发收集器)通常为500 MB YoungGen分配空间和1.5 GB的OldGen空间。

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

推荐阅读更多精彩内容