首先是关于新生代中的内存分布的描述:

新生代中的对象都是“朝生夕死”的对象,所以每次gc存活的对象很少,于是在新生代中采用的垃圾回收算法是“复制算法”。

将新生代的内存分为一块较大的Eden区域和两块较小的Survivor区域。每次使用Eden和其中一块Survivor空间。回收的时候,将Eden和Survivor中还存活着的对象一次性地复制到另一块空间上,最后清理Eden和刚才用过的Survivor空间。

HotPost虚拟机默认Eden和Survivor的大小比例是8:1,也就是每次新生代中可用内存空间为整个新生代容量的90%(80%+10%),只有百分之10%的内存会被浪费。

当Survivor空间不够放的时候,需要依赖其他内存(这里指老年代)进行分配担保。

这是书上(《深入理解Java虚拟机》)对于复制算法的描述。

但在后面更详细地讲内存分配与回收策略的时候:

书上说:在大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机发起一次Minor GC。

这就有点疑惑了,照这么说超过Eden就执行mimor gc,然后survivor只是用来放存活的对象的,那为什么要两个呢?

这是为了解决内存碎片化的问题。

假设我们现在只有一个Survivor空间。

刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区。下一次Eden满了的时候,问题来了,此时进行Minor GC,Eden和Survivor各有一些存活对象,因为只有一个Survivor,所以Eden第二次的gc发现的存活对象也是放在唯一的一个Survivor区域中。但此时把Eden区的存活对象硬放到Survivor区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化。

看图来理解:

(图片来自:https://blog.csdn.net/antony9118/article/details/51425581)

第一个图,是Eden中蓝色的内存装满了,要gc,然后Survivor区中的黄色内存,是上一次gc从Eden过来的存活对象。

第二个图是触发gc后,通过可达性判断,把活着的对象找出来。蓝色的Eden中剩一小丢存活对象,注意Survivor区中的对象也会死掉!所以现在Survivor区的对象也不是从头充满Survivor区域的了。

然后第三个图便是把Eden存活的对象放到Survivor中去,这时就产生了碎片化。

那么要怎么解决这个问题呢?

  1. 试图将Eden区存活的对象转移到survivor中,努力适应这种不连续的空间。但是不连续的空间会导致再分配大对象的时候,由于没有连续的空间来分配,会导致提前垃圾回收。
  2. 将survivor中的所有存活对象向下移动来消除碎片,然后将所有的存活对象移入其中。这样做会降低效率。
  3. 把两个区域中的所有存活对象都转移到完全独立的空间中,也就是第二块Survivor中,这样就可以留出一块完全空着的Eden和Survivor了,下次GC的时候再重复这个流程

显然方案三好点hh,所以我们便要有两个Survivor区。

那么,顺理成章的,应该建立两块Survivor区。

刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到第一块survivor space S0,Eden被清空;等Eden区再满了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入第二块survivor space S1(这个过程非常重要,因为这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间,避免了碎片化的发生)。S0和Eden被清空,然后下一轮S0与S1交换角色,如此循环往复。

看图:

(图片来自:https://blog.csdn.net/antony9118/article/details/51425581)

上述机制最大的好处就是,整个过程中,永远有一个survivor space是空的,另一个非空的survivor space无碎片。

参考文章:

https://blog.csdn.net/antony9118/article/details/51425581

https://www.jianshu.com/p/a5fd5bf93d26

新生代内存中为什么要有两个survivor区的更多相关文章

  1. 在JVM的新生代内存中,为什么除了Eden区,还要设置两个Survivor区

    在JVM的新生代内存中,为什么除了Eden区,还要设置两个Survivor区? 1 为什么要有Survivor区 先不去想为什么有两个Survivor区,第一个问题是,设置Survivor区的意义在哪 ...

  2. JVM内存结构之二--新生代及新生代里的两个Survivor区(下一轮S0与S1交换角色,如此循环往复)、常见调优参数

    一.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...

  3. 为什么新生代内存需要有两个Survivor区

    转载自:http://blog.csdn.net/antony9118/article/details/51425581 在JVM的新生代内存中,为什么除了Eden区,还要设置两个Survivor区? ...

  4. JVM内存结构--新生代及新生代里的两个Survivor区(下一轮S0与S1交换角色,如此循环往复)、常见调优参数

    一.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...

  5. 为什么新生代内存需要有两个Survivor区?

    对于常见的GC算法,我们都应该知道,例如:标记清除算法.复制算法.标记整理算法等.标记清除算法由于回收之后存在大量的内存碎片,存在效率和空间问题!为了解决效率问题,引出了复制算法!熟悉GC算法的小伙伴 ...

  6. JVM体系结构之六:堆Heap之2:新生代及新生代里的两个Survivor区(下一轮S0与S1交换角色,如此循环往复)、常见调优参数

    一.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...

  7. 新生代Eden与两个Survivor区的解释

    文章出处:http://ifeve.com/jvm-yong-generation/ 聊聊JVM的年轻代 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分 ...

  8. 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(一)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...

  9. 游标-----内存中的一块区域,存放的是select 的结果

    游标-----内存中的一块区域,存放的是select 的结果          游标用来处理从数据库中检索的多行记录(使用SELECT语句).利用游标,程序可以逐个地处理和遍历一次检索返回的整个记录集 ...

随机推荐

  1. Codeforces Round #401 (Div. 2) C Alyona and Spreadsheet —— 打表

    题目链接:http://codeforces.com/contest/777/problem/C C. Alyona and Spreadsheet time limit per test 1 sec ...

  2. Codeforces Beta Round #7 D. Palindrome Degree —— 字符串哈希

    题目链接:http://codeforces.com/contest/7/problem/D D. Palindrome Degree time limit per test 1 second mem ...

  3. jquery回顾part1——选择器

    jQuery 选择器 选择器 实例 选取 * $("*") 所有元素 #id $("#lastname") id="lastname" 的元 ...

  4. jsp报An error has occurred. See error log for more details. Argument not valid错误

    An error has occurred. See error log for more details. Argument not valid 翻译过来是:一个错误已经发生.看到更多的细节错误日志 ...

  5. CSS实现文字内容不被截断当超出指定长度时该字符串自动整体换到下一行

    效果图: 1.内容不被截断 span {       overflow:hidden;       white-space:nowrap;       text-overflow:ellipsis;  ...

  6. TCPDUMP 使用详情

    第一种是关于类型的关键字,主要包括host,net,port, 例如 host 210.27.48.2,指明 210.27.48.2是一台主机,net 202.0.0.0 指明 202.0.0.0是一 ...

  7. Lecture 0 --基本说明

    Abstract:本章所记录的知识是后面章节需要的前导知识,请务必仔细读本章,理解涉及的知识点,方便后面章节的学习.本次数据结构笔记主要参考殷人昆的<数据结构(C语言描述)>这本书,需要的 ...

  8. counting the numbers

    题意: 给定$a,b,c$ ,求解满足 $1 \leq m \leq b, 1 \leq n \leq c, a | mn$ 的 $(m,n)$ 数对个数. $a \leq INTMAX$, $b \ ...

  9. 使用you-get下载网页小视频(实际上你可以下载任意你想要的web网页中的内容)

    1. 什么是you-get? You-Get是一个小型的命令行实用程序,用于从Web下载媒体内容(视频,音频,图像),如果没有其他方便的方法可以尝试使用you-get. 2.安装you-get 打开命 ...

  10. Exists 方法

    public void ExistsMethodDemo() { string userId = "123"; string userName = "admin" ...