内容简介:本文会使用排除法的手段,来讲解新生代的区域划分,从而让读者能够更清晰的理解分代回收器的原理,在开始之前我们先来整体认识一下分代收集器。分代收集器会把内存空间分为:老生代和新生代两个区域,而新生代又会分为:Eden 区和两个 Survivor区(From Survivor、To Survivor),来看内存空间分布图,如下:
本文会使用排除法的手段,来讲解新生代的区域划分,从而让读者能够更清晰的理解分代回收器的原理,在开始之前我们先来整体认识一下分代收集器。
分代收集器会把内存空间分为:老生代和新生代两个区域,而新生代又会分为:Eden 区和两个 Survivor区(From Survivor、To Survivor),来看内存空间分布图,如下:
(图片来自 fancydeepin)
可以看出 Eden 和 Survivor 分区的默认比例是 8:1:1,这个值可以通过:–XX:SurvivorRatio 设定,默认值: –XX:SurvivorRatio=8。
顺便说一下,新生代和老生代默认情况下的内存占比是 1:2,该值可以通过:-XX:NewRatio 来设定。
为什么 Survivor 分区不能是 0 个?
如果 Survivor 是 0 的话,也就是说新生代只有一个 Eden 分区,每次垃圾回收之后,存活的对象都会进入老生代,这样老生代的内存空间很快就被占满了,从而触发最耗时的 Full GC ,显然这样的收集器的效率是我们完全不能接受的。
为什么 Survivor 分区不能是 1 个?
如果 Survivor 分区是 1 个的话,假设我们把两个区域分为 1:1,那么任何时候都有一半的内存空间是闲置的,显然空间利用率太低不是最佳的方案。
但如果设置内存空间的比例是 8:2 ,只是看起来似乎“很好”,假设新生代的内存为 100 MB( Survivor 大小为 20 MB ),现在有 70 MB 对象进行垃圾回收之后,剩余活跃的对象为 15 MB 进入 Survivor 区,这个时候新生代可用的内存空间只剩了 5 MB,这样很快又要进行垃圾回收操作,显然这种垃圾回收器最大的问题就在于,需要频繁进行垃圾回收。
为什么 Survivor 分区是 2 个?
如果 Survivor 分区有 2 个分区,我们就可以把 Eden、From Survivor、To Survivor 分区内存比例设置为 8:1:1 ,那么任何时候新生代内存的利用率都 90% ,这样空间利用率基本是符合预期的。再者就是虚拟机的大部分对象都符合“朝生夕死”的特性,所以每次新对象的产生都在空间占比比较大的 Eden 区,垃圾回收之后再把存活的对象方法存入 Survivor 区,如果是 Survivor 区存活的对象,那么“年龄”就 +1 ,当年龄增长到 15 (可通过 -XX:+MaxTenuringThreshold 设定)对象就升级到老生代。
总结
根据上面的分析可以得知,当新生代的 Survivor 分区为 2 个的时候,不论是空间利用率还是程序运行的效率都是最优的,所以这也是为什么 Survivor 分区是 2 个的原因了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Java微服务新生代之Nacos
- Java微服务新生代Nacos-配置管理
- BAT、独角兽环伺,新生代人脸识别算法公司还有哪些机会?
- BAT、独角兽环伺,新生代人脸识别算法公司的出路在哪?
- db2 定义分区表和分区键
- HBase漫谈 | HBase分区过多影响&合理分区数量
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Release It!
Michael T. Nygard / Pragmatic Bookshelf / 2007-03-30 / USD 34.95
“Feature complete” is not the same as “production ready.” Whether it’s in Java, .NET, or Ruby on Rails, getting your application ready to ship is only half the battle. Did you design your system to......一起来看看 《Release It!》 这本书的介绍吧!