基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
面试官:熟悉JVM吗?为什么新生代内存需要有两个Survivor区?
面试官:熟悉JVM吗?为什么新生代内存需要有两个Survivor区?
阅读
1
2020-06-23
: 小
Flag
实现,
在
JVM
的新生代内存中,为什么除了
Eden
区,还要设置两个
Survivor
区?
1 为什么要有Survivor区
先不去想为什么有两个
Survivor
区,第一个问题是,设置
Survivor
区的意义在哪里?
如果没有
Survivor
,
Eden
区每进行一次
Minor
GC
,存活的对象就会被送到老年代。老年代很快被填满,触发
Major
GC
(因为
Major
GC
一般伴随着
Minor
GC
,也可以看做触发了
Full
GC
)。
老年代的内存空间远大于新生代,进行一次
Full
GC
消耗的时间比
Minor
GC
长得多。你也许会问,执行时间长有什么坏处?频发的
Full
GC
消耗的时间是非常可观的,这一点会影响大型程序的执行和响应速度,更不要说某些连接会因为超时发生连接错误了。
好,那我们来想想在没有
Survivor
的情况下,有没有什么解决办法,可以避免上述情况:
显而易见,没有
Survivor
的话,上述两种解决方案都不能从根本上解决问题。
我们可以得到第一条结论:
Survivor
的存在意义,就是减少被送到老年代的对象,进而减少
Full
GC
的发生,
Survivor
的预筛选保证,只有经历
16
次
Minor
GC
还能在新生代中存活的对象,才会被送到老年代。
2 为什么要设置两个Survivor区
设置两个
Survivor
区最大的好处就是解决了碎片化,下面我们来分析一下。
为什么一个
Survivor
区不行?第一部分中,我们知道了必须设置
Survivor
区。假设现在只有一个
survivor
区,我们来模拟一下流程:
刚刚新建的对象在
Eden
中,一旦
Eden
满了,触发一次
Minor
GC
,
Eden
中的存活对象就会被移动到
Survivor
区。这样继续循环下去,下一次
Eden
满了的时候,问题来了,此时进行
Minor
GC
,
Eden
和
Survivor
各有一些存活对象,如果此时把
Eden
区的存活对象硬放到
Survivor
区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化。
我绘制了一幅图来表明这个过程。其中色块代表对象,白色框分别代表
Eden
区(大)和
Survivor
区(小)。
Eden
区理所当然大一些,否则新建对象很快就导致
Eden
区满,进而触发
Minor
GC
,有悖于初衷。
碎片化带来的风险是极大的,严重影响
JAVA
程序的性能。堆空间被散布的对象占据不连续的内存,最直接的结果就是,堆中没有足够大的连续内存空间,接下去如果程序需要给一个内存需求很大的对象分配内存。。。画面太美不敢看。。。这就好比我们爬山的时候,背包里所有东西紧挨着放,最后就可能省出一块完整的空间放相机。如果每件行李之间隔一点空隙乱放,很可能最后就要一路把相机挂在脖子上了。更多面试题,欢迎
那么,顺理成章的,应该建立两块
Survivor
区,刚刚新建的对象在
Eden
中,经历一次
Minor
GC
,
Eden
中的存活对象就会被移动到第一块
survivor
space
S0
,
Eden
被清空;等
Eden
区再满了,就再触发一次
Minor
GC
,
Eden
和
S0
中的存活对象又会被复制送入第二块
survivor
space
S1
(这个过程非常重要,因为这种复制算法保证了
S1
中来自
S0
和
Eden
两部分的存活对象占用连续的内存空间,避免了碎片化的发生)。
S0
和
Eden
被清空,然后下一轮
S0
与
S1
交换角色,如此循环往复。如果对象的复制次数达到
16
次,该对象就会被送到老年代中。下图中每部分的意义和上一张图一样,就不加注释了。
上述机制最大的好处就是,整个过程中,永远有一个
survivor
space
是空的,另一个非空的
survivor
space
无碎片。
那么,
Survivor
为什么不分更多块呢?比方说分成三个、四个、五个?显然,如果
Survivor
区再细分下去,每一块的空间就会比较小,很容易导致
Survivor
区满,因此,我认为两块
Survivor
区是经过权衡之后的最佳方案。
说明
本人水平有限,不当之处希望各位高手指正。另外,文中的插图都是我自己在
word
的
smart
art
中绘制的,看起来不精致请见谅。
出处:
blog
.
csdn
.
net
/
antony9118
/
article
/
details
/
51425581
? ~
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
MySQL索引优缺点、何时需要/不需要创建索引、索引及sql语句的优化
下一篇:
面试官:你真的清楚 i = i++和 i = ++i 的区别吗?
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目