YGC前后新生代变大?

问题描述

我们都知道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不会变化的情况。

时间: 2024-07-30 22:00:12

YGC前后新生代变大?的相关文章

为什么MathType编辑公式变大?

  MathType编辑公式变大的情况如下图所示: MathType编辑界面公式变大的情况 其实这个问题的解决很简单,具体操作如下: 1.按照自己的习惯打开MathType公式编辑器进入到公式编辑界面,或者直接在刚才按错的界面下保持不动. 2.在这个编辑界面中,用鼠标点击MathType菜单中的"视图"--"缩放"--"200%",这个时候你就会发现工作区域中变大的公式已经恢复到正常了.200%的比例是我们在正常工作时MathType的默认设置,

java-swing 实现类似QQ下拉框图片自由变大缩小

问题描述 swing 实现类似QQ下拉框图片自由变大缩小 swing jComboBox实现类似QQ下拉框图片自由变大缩小并加入关闭按钮[如何定位到按钮] 请提供思路和想法 谢谢你们....

ps怎么把眼睛变大

  原图: 效果图: ps将研究变大的具体操作步骤如下: 1.首先在原图的基本上按住ctrl+J拷贝一个图层, 2.现在开始对复制图层上面,在新建一个图层,并且填充%50的灰色,如图所示: 3.降低该灰色层透明度,使下面一层可以显现出来即可.如图所示: 4.分别用黑色画笔和白色画笔在灰色图上描出如下图所示: 5.把灰色图层透明度恢复到100%,然后保存为PSD文件. 6.刚刚保存为PSD文件后,原来的还没有关,不要关掉,现在你要把那个灰色图层的眼睛关掉,就是先出下面的背景副本图层. 7.执行"滤

用JS将网页窗口由小变大

js|网页 有没有这种经历,当你打开一个链接的时候,浏览器窗口由小变大,呈现一个渐变的过程.下面,我们就来介绍这种动态效果的由来,大家可要看仔细了. 这种程式的思路就是先根据浏览器的可利用的宽度和高度,算出一个中心坐标点,然后每次都把窗口定位到这个点上,再算出相应窗口的变大尺寸,循环50次,从而最终回到浏览器最大化时的状态. 在和之间插入下列代码: <SCRIPT LANGUAGE="javascript"> <!-- Begin function expand()

可牛影像眼睛变大功能制作眨眼美女

可牛影像中的美容功能不仅可以把眼睛变大也是可以把眼睛变小的哦 现在牛牛就教你利用眼睛变大的功能和自己制作闪图的功能 来制作动感眨眼美女 首先看一下效果图 原图 : 最终效果: 下面就来看一下具体的做法 第一步 打开一张美女的图片 找到美容--眼睛变大功能 第二步 分别将放大笔力度和大小调整好然后分别放在美女的两个眼睛中间点几个点到合适为止 第三步 调整好保存后 找到动感闪图功能中的自己制作闪图功能 点"添加一帧" 第四步 分别将原图和制作好的美女图添加进去 第五步 点预览闪图效果 调整

文字从小变大显示

 <html> <head> <title>网页特效|Linkweb.cn/Js|---文字从小变大显示</title> <style type="text/css"> <!-- body {  font-family: "宋体"; font-size: 9pt; margin-top: 0px; margin-left: 0px; margin-right: 0px} A { COLOR: blac

iSee让MM眼睛瞬间变大 跻身非主流

网络上流行的非主流美女,眼睛都是大大的.米错啦,无论MM是小眼或单眼皮,双眼皮都好,统统都可以用iSee来做出大眼睛效果.而且操作超超简单,鼠标一点,眼睛瞬间变大,让你也可以非主流一把. 先看原图和效果图. 原图: (图1) 大眼睛效果图: (图2) 1.iSee打开图1.选择"右侧工具条"-人像美容-眼睛变大. (图3) 2.进入"眼睛变大"的处理界面,选择"放大笔". 笔头大小:37 (放大笔最好能接近并稍微大于眼睛的大小) 放大力度:30

鼠标放到图片上慢慢变大

 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>网页特效观止|www.jscode.cn| --- 鼠标放到图片上慢慢变大,移开后图片又慢慢变小</title>   </head>   <body> <img id=MainImg onmouse

使Win8屏幕上的文本变大或变小

  无需更改显示器或便携式计算机屏幕的屏幕分辨率即可使文本(及其他类似图标的项目)变大. 这样,你既可以使文本易于查看,又可以让显示器或便携式计算机设置为最佳分辨率. 整理互联网和微软官方文档发布. 通过以下方式打开"屏幕分辨率":从屏幕的右边缘向中间轻扫,点击"搜索"(如果使用鼠标,则指向屏幕的右上角,然后将指针向下移动,再单击"搜索"),在搜索框中输入"显示",然后依次点击或单击"设置"和"显