问题描述


我们都知道gc是为了释放内存,但是你是否碰到过ygc前后新生代反增不减的情况呢?gc日志效果类似下面的:

2016-05-18T15:06:13.011+0800: [GC [ParNew (promotion failed): 636088K->690555K(707840K), 0.2958900 secs][CMS: 1019739K->1019733K(1310720K), 2.6208600 secs] 1655820K->1655820K(2018560K), [CMS Perm : 205486K->205486K(262144K)], 2.9174390 secs] [Times: user=3.74 sys=0.01, real=2.91 secs]

从上面的gc日志来看,我们新生代使用的是ParNew,而老生代用的是CMS GC,我们注意到ParNew的效果是新生代从636088K新增到了690555K,这是什么情况?

原理分析


要解释这个问题,我们先要弄清楚YGC的过程,parNew是新生代的gc算法,简单来说从gc roots开始扫描对象,当扫到一个只要是属于新生代的对象就将其挪到to space,但是老的对象还不会做释放,直到gc完成之后再看是否释放老的对象(比如说上面我们看到了promotion failed的关键字,意味着晋升失败了,也就是说to和old都装不下新生代晋升来的对象,那么在这种情况下其实是不会对eden和from里的老对象做释放的,尽管to space里已经可能存在一份副本了),但是在gc前后不管是否晋升成功,都会对from space和to space做一个对换,也就是原来的from变成to,原来的to变成from,再来看看打印gc前后内存变化的代码

void GenCollectedHeap::print_heap_change(size_t prev_used) const {if (PrintGCDetails && Verbose) {gclog_or_tty->print(" "  SIZE_FORMAT"->" SIZE_FORMAT"("  SIZE_FORMAT ")",prev_used, used(), capacity());} else {gclog_or_tty->print(" "  SIZE_FORMAT "K""->" SIZE_FORMAT "K""("  SIZE_FORMAT "K)",prev_used / K, used() / K, capacity() / K);}
}size_t GenCollectedHeap::used() const {size_t res = 0;for (int i = 0; i < _n_gens; i++) {res += _gens[i]->used();}return res;
}size_t DefNewGeneration::used() const {return eden()->used()+ from()->used();      // to() is only used during scavenge
}

从上面代码我们知道,gc之后的内存情况是used()方法返回的,其中新生代的used方法返回的是eden+from的内存,同样的上面的prev_used也是这么计算的,只是发生在gc之前,这样一来,根据我上面提到的情况,在gc之后不管是否成功都会做一次from和to的swap,那么gc之前新生代的使用大小,其实是gc之前eden+from的使用大小,而gc之后的新生代的使用大小,其实是eden+原来的to现在使用的大小,原来的to现在使用的大小其实就是在gc过程中将eden和from拷贝过来的对象所占的大小。

综上分析你应该知道为什么会出现这种情况了,其实是一种特殊情况,只有在出现promotion failed的情况下才会发生这样的情况,因为在这个情况下存在to里新增对象,而from和eden不会变化的情况。

YGC前后新生代变大?相关推荐

  1. 查看回调几个选项含义_C 盘总是莫名变大?更改这个文件位置至少腾出几个 G !...

    Windows 系统盘之所以神不知鬼不觉地变大,除了系统升级.系统垃圾以及软件缓存等原因之外,还有可能有虚拟内存空间.比如 pagefile.sys 文件. 你的高效生活视频书. 打开 Windows ...

  2. javascript基础——文字变大变小className的使用及JS浮动的兼容用法

    文字变大变小,详情页比较常见的那种 <!DOCTYPE html> <html lang="en"> <head><meta charse ...

  3. 牙齿间隙变大怎么办_牙齿矫正会让牙缝变大吗?

    很多做牙齿矫正的朋友,都对牙齿矫正会让牙缝变大等问题有很多的疑问,今天就给大家科普一下关于牙齿矫正会不会让牙缝变大的问题. 牙齿矫正会不会让牙缝变大? 在做牙齿矫正之前,如果检查牙齿后发现有牙结石.食 ...

  4. css3宽度变大动画_不会仪表?太尴尬了。14种动画让你轻松掌握各种流量计工作原理...

    相信很多同仁都和小编一样,在工厂干活做电气维护,电气仪表不分家.没办法,老板为了节约成本,很多公司是不配备专门的仪表工的.按理说,仪表工和电工是二个不同的工种,但是老板不理会这个啊.啊,李工,这个仪表 ...

  5. 技术人生:我喜欢年纪不断变大

    随着年纪的变大,阅历增加.经验增加.知识增加.收入增加.职位升高,或许更重要的是:我希望再过几年,我能过我想过的日子. 转载于:https://www.cnblogs.com/happyframewo ...

  6. html语言把字变大,css怎么让字体变大?

    css可以通过font-size属性让字体变大,font-size属性可设置字体的尺寸.所有主流浏览器都支持font-size属性. font-size 属性可设置字体的尺寸. 说明 该属性设置元素的 ...

  7. 蚂蚁变大象:浅谈常规网站是如何从小变大的(转)

    2005年,我开始和朋友们开始拉活儿做网站,当时第一个网站是在linux上用jsp搭建的,到后来逐步的引入了多种框架,如webwork.hibernate等.在到后来,进入公司,开始用c/c++,做分 ...

  8. 华为手机下拉菜单变大_不能不知的华为手机菜单栏,知道3个的算你手机没白买!...

    大家都知道华为手机有很多好用的功能,那么华为手机菜单栏的这些按钮都表示什么意思?你知道吗?今天咱们就一起来看看! 第一行 1.WLAN 这个是我们的无线网络按钮,大家可以在里面选择自己需要连接的网络, ...

  9. CSS: 首字母字体变大时下划线不对齐的解决方法

    昨天在写2017年百度ife任务六的时候遇到了一个排版问题,需要首字母字体变大的同时,下划线对齐. 首先使用了 ::first-letter伪元素的选择器,将字体变大后,发现下划线没法对齐,代码如下: ...

最新文章

  1. 深入浅出ES6(一):ES6是什么
  2. 设计模式(二十四)解释器模式
  3. charles请求转发_用免费开源的frp实现内网穿透,使用nginx转发的方式去掉端口号...
  4. 智慧交通day02-车流量检测实现01:总览
  5. Bluetooth篇 开发实例之六 蓝牙RSSI计算距离
  6. 终于来了!iOS 13大更新发布,新功能均与新冠疫情有关
  7. java的Scanner类
  8. 51 nod 1006 最长公共子序列Lcs
  9. Linux下QT创建项目错误处理
  10. 接收POst数据流数据
  11. pytest学习(2)
  12. 无线系列-无线通信系统组成
  13. 走一波 程序员必备精品软件大全
  14. RFC2544时延测试——信而泰网络测试仪实操
  15. 案例教程:一步步教你ps制作二寸照片
  16. 自封装验证手机号码、邮箱格式、身份证号的工具
  17. 【51单片机】普中A2开发板 模块化编程 单片机入门 实例教学目录
  18. 2019 ICPC南昌邀请赛比赛游记 队伍名:莫比乌斯
  19. 什么是基因间隔区和内含子?
  20. 离线下载pytorch安装包

热门文章

  1. 部分 CM11 系统 Android 平板执行植物大战僵尸 2 黑屏的解决的方法
  2. JS获取用户控件中的子控件Id
  3. 云计算成IT反“腐”后盾-《中国电子报》2013年5月特刊
  4. 【转】OpenGL反走样
  5. OSPF邻接形成过程
  6. 【Git】认识各种开源协议及其关系
  7. excel 案例素材_Excel用了十年,函数千千万,最牛的还是vlookup
  8. javaweb网上书店项目设计_计算机毕业设计能不能用成品?
  9. STL标准库-容器-set与map
  10. (JAVA)String常用的方法