本章只针对变化区域做讲解,其他不变的区域不做讲解。
先看看java7(包含java7)以前的jvm内存分布图:
方法区(官方叫做永久代,方法区不知道怎么延申出来的名字):
1.存放类的加载信息:类的修饰符,类名,类的属性(字段),属性修饰符,类的方法,方法修饰符等
2.存放运行时常量,,静态变量,全局字符串常量
堆:
堆主要存放对象的,堆也分好几个区域:伊甸园,from survivor,to survivor(这三个区域叫新生代区)old generation
Eden区:新new出来的对象放在此区域,此区域会频繁执行MinorGC(轻量的)。
from survivor:当Eden区执行MinorGC后遗留下来的对象会被分到该区域
to survivor:被频繁执行MinorGC后遗留下的对象分到此区域,下一步就会分到老年代
old generation:MinorGC在清理对象的时候会使用计数法给遗留下来的对象赋值,每执行一次累计加1,当对象计数值到达15时会复制到老年区(15是初始值,可以自己设置),老年区的对象不会被MinorGC检查,但是当老年区的内存小于Eden时,会触发一次FullGC去回收老年区的对象,在每次执行FullGC时,都会先在新生代区执行一次MinorGC,然后执行fullGC.
再看下java8的内存模型
百度搜索java8内存模型,很多图片都还包含方法区,但实际上java8以后(含java8)是去掉了永久代了,也就是不存在方法区了。
java8多了一个MetaSpace元数据区,此区域是使用本地内存(应该是jvm内存模型之外的类型,也就是计算机内存),之前的类加载信息是存放在方法区的,java8是存在此元数据区,
然后把java7以前本来存放在方法区的常量池,也移到了堆中。
在学习jvm时,发现网上很多博客的类容都是错误的,我也是通过看不同的博客才知道很多都对不上,很多博客都存在错误和偏差。所以需要多看多比较,出现偏差的地方载去网上多查一下。真理源自实践。