概述
直接先上图:
可以看到在堆内存中分了Old区和young区两个大区,young区又分为Eden区和Survivor区(简称S区),S区又分成了S0和S1.
我们都知道,堆内存存放的是成员变量,也称为属性,在方法外、在类内定义的变量。随着对象的创建而产生,随着对象的销毁而收回。而不同的对象生命周期也不同,因此生命周期较长的对象存放在Old区,生命周期较短的对象存放在young区.
young区为什么会分为Eden区和S区呢?
其实可以举个例子:
比如家里要扔垃圾,假设垃圾一天就满,我们有两种方式扔垃圾
- 一天扔一次,一周扔7次. 每次只扔1袋垃圾
- 一周扔一次,一次扔7袋.
假设我们一周扔一次的话会产生哪些问题呢?
大量的垃圾存留在房间内,导致空间紧张,去扔的时候我需要一袋一袋的去捡起来,浪费时间,并且我需要同时拿7袋垃圾,对身体负载较大.
回到内存模型中:
对于对象来说,其实大多数的对象生命周期都是较短的,对于young区来说,如果不分区的话,这些生命周期较短的对象由于未达到内存的临界值而无法被销毁,这样的话当达到临界值时的GC操作会因为存在大量的无用对象而消耗较长的时间.而S区其实就是作为缓冲作用,新创建的对象会进入Eden区,当Eden区空间不足时,Young区就会进行一次GC操作,无用的对象清除,有用的进入S区.
S区为什么分为S0和S1区?
当Eden区的对象进入S区时,不同的对象进入S区占用的空间都是随机分布的,如果只有一个S区会造成空间的不连续使用,因此分为相同大小的S0和S1,当出发GC时,存活的对象都会从S0转移到S1,这样就保证了空间的连续使用,当然这样也会造成一定的空间浪费. Eden:S0:S1 = 8:1:1
当S区内存空间不足时,对象就会进入Old区了,当Old区内存也不足时,Old区会进行一次GC操作,GC后依然不足则会报OUT OF MEMORY(OOM)错误了.
因此如果出现OOM错误其实无外乎两种情况了:
1.代码问题,重点可排查递归,循环创建对象的代码块.
2.项目较大,有用的对象较多导致内存不足.可修改tomcat配置文件,将内存调大一些.
Over
最后
以上就是炙热煎蛋为你收集整理的JVM学习笔记---------堆内存模型的全部内容,希望文章能够帮你解决JVM学习笔记---------堆内存模型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复