JVM-GC基础

基本的垃圾回收算法

引用计数(Reference Counting)

增加一个引用,引用计数加1,去掉一个引用,引用计数减1,然后回收那些引用计数为0的对象
问题:无法处理循环引用问题(例如A、B两个对象互相引用,但没有其他对象引用它们,这时它们也无法被回收)

标记-清除(Mark-Sweep)

从引用根节点开始标记所有被引用的对象,然后遍历整个堆,清除未标记的对象
问题:产生碎片

标记-清除

复制(Copying)

首先将内存空间分为对等的两半,每次只使用其中一半
每次回收时,遍历当前使用区域,将正在使用的对象复制到另外一个区域
好处:一次遍历即可,且不会产生碎片
问题:需要两倍空间

复制

标记-整理(Mark-Compact)

从引用根节点开始标记所有被引用的对象,然后遍历整个堆,清除未标记的对象,并把存活对象压缩到一块
好处:避免了空间的浪费,且不会产生碎片

标记-整理

比较

空间:复制>标记-清除=标记-整理(复制需要两倍空间)
时间:复制<标记-清除<标记-整理(复制最快,一次遍历即可;标记-整理比标记-清除要慢,因为除了清除之外,还要移动数据)

JVM分代结构

JVM内存采用分代结构,分别为Young、Tenured、Permanent,其中Young又细分为Eden和两个大小相同的Survivor区:From和To。

分代结构

分代依据

  1. 绝大部分的对象都是临时对象
  2. 不同对象的生命周期不同,采用不同的算法,可以提高不同的效率

JVM GC过程

GC过程
  1. 新建的对象都在Eden中创建
    大的对象直接在Old中创建:1)超过-XX:PretenureSizeThreshold设置,2)大于整个Eden
    如果Eden满了,则触发MinorGC

  2. MinorGC
    暂停程序
    将Eden和From中存活的对象复制到To,同时各个对象的年龄值加1(MinorGC后,Eden和From都是空的)
    如果To满了,则将对象移到Old,如果此时Old满了,则发送Promotion Failed错误,触发FullGC
    如果对象的年龄超过-XX:MaxTenuringThreshold,也移到Old(这里有一个动态对象年龄的概念:不是每次都要求对象的年龄一定要超过-XX:MaxTenuringThreshold才晋升到Old,如果Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入Old)

  3. FullGC
    如果Old满了,触发FullGC
    如果Perm满了,触发FullGC
    暂停程序(CMS算法的整个过程可以并行执行,只需短暂暂停程序2次)
    回收Old,如果回收后还是满了,则抛出OutOfMemoryError: Java heap space
    默认情况下,JVM是不回收Perm区的,要回收需要使用CMS算法,并设置-XX:+CMSClassUnloadingEnabled, -XX:+CMSPermGenSweepingEnabled,如果回收后还是满了,则抛出OutOfMemoryError: PermGen space

JVM GC算法

串行

效率高,但无法利用多核,一般在小程序使用,使用-XX:+UseSerialGC打开

串行

并行

对Young并行收集,使用-XX:+UseParallelGC打开
JDK6.0后可对Old进行并行收集,使用-XX:+UseParallelOldGC打开

并行

并发

保证大部分回收工作并发执行(应用不暂停),适合响应要求高的应用,使用-XX:+UseConcMarkSweepGC打开

并发

G1

待补

比较

Serial Throughput CMS G1
参数 -XX:+UseSerialGC -XX:+UseParallelGC -XX:+UseConcMarkSweepGC, -XX:+UseParNewGC -XX:+UseG1GC
Young(都是暂停整个应用) 单线程 多线程 多线程 多线程
Old 单线程,暂停应用,压缩 多线程,暂停应用,压缩 单或多线程,部分暂停,不压缩 多线程,部分暂停,压缩
增加CPU使用率,产生碎片,如果没有足够的CPU或者碎片太多,则退化成serial gc 增加CPU使用率,适合Heap大于4G的情况,Old区也是从一个region拷贝到另外一个region

G1和CMS的机制是差不多的,只是G1把old分区了,这样更有利于多线程的扫描
CMS每次清除后,都不会压缩整理的,会产生碎片,而G1每次都像young那样,进行数据移动,也就解决了碎片的问题

选择

  1. 如果heap少于100MB,选择Serial
  2. 对于TPS,如果CPU够用,则选择并发GC,如果CPU使用率较高,则选择Throughput
  3. 对于平均响应时间,通常Throughput比并发GC要好
  4. 对于90%或99%的响应时间,并发GC比Throughput要好
  5. 如果选用并发GC,heap少于4G选择CMS,大于4G选择G1(这个保留,对G1算法不了解,了解后再修正)

GC Root

垃圾回收从Root开始,栈是程序真正执行的地方,所以从栈开始找,而栈又属于线程独有,所以从所有的线程的栈开始找

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

推荐阅读更多精彩内容

  • 原文阅读 前言 这段时间懈怠了,罪过! 最近看到有同事也开始用上了微信公众号写博客了,挺好的~给他们点赞,这博客我...
    码农戏码阅读 5,948评论 2 31
  • 作者:一字马胡 转载标志 【2017-11-12】 更新日志 日期更新内容备注 2017-11-12新建文章初版 ...
    beneke阅读 2,184评论 0 7
  • JVM架构 当一个程序启动之前,它的class会被类装载器装入方法区(Permanent区),执行引擎读取方法区的...
    cocohaifang阅读 1,648评论 0 7
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,545评论 3 83
  • 转载blog.csdn.net/ning109314/article/details/10411495/ JVM工...
    forever_smile阅读 5,353评论 1 56