首页 > 其他分享 >浅谈新生代为什么要分三块区域并且比例为什么是8:1:1

浅谈新生代为什么要分三块区域并且比例为什么是8:1:1

时间:2023-07-31 19:48:06浏览次数:42  
标签:为什么 浅谈 要分 对象 s1 s0 新生代 存活 年代

       如题,最近在网上看到了一个某大厂的面试题:“新生代为什么分三块区域且比例为什么是8:1:1"?网上答案比比皆是,我是没搜到什么有价值的答案,今天结合这个题目谈谈自己的粗浅想法,如有不对还望指正;另外需要说明的是,接下来聊的都是基于G1之前的垃圾收集器;
       首先,我们假设新生代如果不分代会发生什么:如果不分代的话那么堆内存就是由一块新生代,一块老年代组成,当发生mionrGc时,收集器不管采用的是古老的Serial还是Parallel Scavenge,都会使用标记-复制算法将新生代中存活的对象直接复制到老年代;这时候会产生如下问题:

  1. 原先本来可作为担保空间的老年代直接用来容纳了新生代每次gc存活的对象,导致了标记-复制算法没有了担保空间,大大新增了fullGC发生的概率和次数
  2. 无论对象年龄与否,只要熬过一次垃圾回收即可进入老年代,使进入老年代的成本降低,加大了老年代的负担,同样会增加fullGc的次数

tips
正常情况下,对象何时进入老年代呢?
1、对象熬过一定的垃圾回收次数(不同的收集器要求不同,最大不会超过15)后进入老年代
2、动态年龄判定:新生代每次进行垃圾回收时,当e+s0或1区对象复制到另一个s1或0区时,会将对象年龄按从小到大的顺序进行累加,当对象大小累加到超过s1或0区的目标存活率时(默认50%),年龄大于等于当前计算对象年龄的对象直接进入老年代
3、分配在eden区的对象是大对象时直接到老年代分配

所以由上可得,新生代必须分代,此时我们假设将新生代分成一个e区一个s区,如图:

       我们来看下在此分代模式下进行mionrGC会发生什么,第一次gc时存活对象由e区进入s区然后清空e区,此时老年代也可以起担保作用,一切看起来都很正常;但是如果再发生第二次gc会怎样呢,此时e区有存活对象,而容纳第一次gc时存活对象的s区也肯定会有存活对象,此时需要将e,s区的存活对象复制到老年代;此时,问题也就显而易见了,与不分代的时候情形一样了,对象只能进入老年代;
       所以我们要将新生代再开辟一块区域来当作一个拦截器,不让不达年龄的对象直接接入老年代;结构如图:

       此时新生代分成了e区,s0区和s1区;这时候再发生mionrGc就不会有上面出现的问题了:第一次GC时存活对象由e进入s0,然后清空e区;第二次gc时将e区和s0区的存活对象复制到s1区,清空e区和s0;第三次将e区和s1的对象复制到s0,清空e和s1......如此反复,直到对象年龄达标或者s区(s0或s1)容不下存活对象时再晋升到老年代,这样也就降低了老年代的压力,减少了fullGc的次数;

  • 以上的分析假设了各种不分块或分两块的利弊,所以个人认为的新生代分区或分三区的原因如下:
    1、降低老年代的内存分配压力,通过设置两个s区来对年轻对象进行拦截,降低fullGc的次数
    2、分三代能使老年代作为担保来应付s区容不下存活对象的情况

tips
GC的分代假说:
1、弱分代假说:大部分对象都是朝生夕灭的
2、强分代假说:熬过越多次垃圾收集的对象越难被回收
3、跨代引用假说:跨代引用的对象相比同代引用属于极少数

接下来我们来讨论下为什么e:s0:s1默认是8:1:1?
       根据<深入理解虚拟机>一书里的描述,IBM的一项研究表明新生代中有98%的对象是朝生夕灭的,换言之,每次mionrGC后存活的对象应该小于等于2%,所以看起来采用复制算法的新生代似乎可以不用将内存分成大小相等的两块了,但考虑到实验偏差以及实际情况的多样性,jvm默认预留了10%的内存用于存放存活对象,此时结合上文描述的,新生代最优应该分成三块,所以得再预留一块10%的内存给s区,那么自然剩下的80%就是e区的大小了;

标签:为什么,浅谈,要分,对象,s1,s0,新生代,存活,年代
From: https://www.cnblogs.com/darling2047/p/17594293.html

相关文章

  • 为什么不建议在 Docker 中跑 MySQL
    容器的定义:容器是为了解决“在切换运行环境时,如何保证软件能够正常运行”这一问题。目前,容器和Docker依旧是技术领域最热门的词语,无状态的服务容器化已经是大势所趋,同时也带来了一个热点问题被大家所争论不以:数据库MySQL是否需要容器化?认真分析大家的各种观点,发现赞同者仅仅是......
  • 浅谈php伪协议的运用
    浅谈php伪协议的运用(133条消息)PHPFilter伪协议Trick总结_php伪协议rot13的用法_swtre33的博客-CSDN博客php死亡exit()绕过-xiaolong'sblog(xiaolong22333.top)0x00ctf中常见的伪协议种类在CTF比赛中,常常会使用PHP伪协议来进行一些有趣的挑战。PHP伪协议是一种特殊的U......
  • git 为什么merge记录时有时无
    之前在merge完分支的时候,在commit记录中,有时会会出现merge记录,有时就没有。在查了相关资料,原因如下:是否出现merge记录判别规则:自己分支是否对目标分支以前的提交时间线有改动,即如果自己分支的提交记录与目标分支的现有记录完全重合时,提交不会产生merge记录;如果提交是对目标分......
  • 浅谈 dijkstra 与其它文章并没有谈到的一些问题
    讲一个小故逝今天做到了一道很典的题目P1875,我发现我其实并不太会,然后在我看完了题解剽题解的屑以后,我发现我对dijkstra的理解仅仅停留在它的过程,而没有深入挖掘dijkstra的正确性以及它的本质等等。所以这篇文章会从另一个角度来看看dijkstra。也许这是dijkstra的本质吧,还......
  • 浅谈SQL注入及其防御方法
    昨晚跟学生们在群里讨论到什么是SQL注入的时候,硬挤出来了一个比喻.码字不易,特整理记录如下.  首先,电脑里面的语言分两种,编译型,解析型(脚本型).比如PHP就是解析型,C就是编译型.由于SQL语句可以在这两类语言下执行,所以为了充分明白是什么导致了SQL注入漏洞,我......
  • 浅谈数据库分库分表
    目录1.分库分表是什么2.为什么进行分库分表3.有哪些解决方案4.总结本文主要介绍数据库分库分表相关的基础知识,包括分库分表是什么,为什么要分库分表,以及有哪些解决方案。1.分库分表是什么数据库分库分表,用英文表示是"databasesharding"or"databasepartitioning"。分库分表......
  • 为什么使用 CDN 需要 Angular 应用正确返回 HTTP 200 和 404 状态码
    CDN(ContentDeliveryNetwork)是内容分发网络,它的目的是通过在各地建立节点缓存数据,使用户可以就近获取数据,从而提高数据获取的速度和稳定性。Angular是一种用于构建客户端应用的开发平台。它带来了一种新的方式来构建应用,完全是在浏览器中运行,无需借助任何后端服务。HTTP200......
  • 浅谈AFL++ fuzzing(上):如何用进行有效且规整的fuzzing
    适用于白盒fuzzinginputcorpus收集语料库对于模糊测试工具而言,我们需要为其准备一个或多个起始的输入案例,这些案例通常能够很好的测试目标程序的预期功能,这样我们就可以尽可能多的覆盖目标程序。收集语料的来源多种多样。通常目标程序会包含一些测试用例,我们可以将其做位我......
  • 为什么学编程都建议不要用拼音命名?
    前言知乎上有个提问:为什么学编程都建议不要用拼音命名?↓↓↓   不知道身为程序员的你,曾经有没有用拼音在程序代码中命名变量名、方法名、注释等的经历?作为国内的程序员,可能有小伙伴会埋怨,编程语言和开发工具都已经全英文了,用拼音命名怎么了又,不好吗。现如今汉语普及......
  • 浅谈矿井电网选择性绝缘在线监测技术研究
    摘要:通过研究单相漏电时零序电压的变化规律,研究了矿井电缆绝缘下降检测方法及动力电缆附加低频信号取样技术,结合常规漏电保护技术,开发了动力电缆绝缘参数在线监测系统及配套软件,实现了对矿井低压供电系统每一分支电缆的绝缘在线监测,达到选择性漏电保护的目的。关键词:矿井电网;绝缘下......