三种JVM
1.Sun公司 HotSpot
2.BEA JRockit
3.IBM J9 VM
堆
一个JVM只有一个堆内存,堆内存的大小是可以调节的。
VM options:
image.png
Java6和6之前,常量池是存放在方法区(永久代)中的。
Java7,将常量池是存放到了堆中。
Java8之后,取消了整个永久代区域,取而代之的是元空间。运行时常量池和静态常量池存放在元空间中,而字符串常量池依然存放在堆中。
在JDK1.7之前运行时常量池逻辑包含字符串常量池存放在方法区, 此时hotspot虚拟机对方法区的实现为永久代
在JDK1.7 字符串常量池被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是hotspot中的永久代
在JDK1.8 hotspot移除了永久代用元空间(Metaspace)取而代之, 这时候字符串常量池还在堆, 运行时常量池还在方法区, 只不过方法区的实现从永久代变成了元空间(Metaspace)
堆内存还要细分为三个区域:
新生区(伊甸园区)New
老年区 old
永久区 Perm
image.png
图 堆内存详细划分
GC垃圾回收,主要是在伊甸园区和养老区~ 假设内存满了,OOM,堆内存不够! java.lang.OutOfMemoryError:Java heap space 永久存储区里存放的都是Java自带的 例如lang包中的类 如果不存在这些,Java就跑不起来了 在JDK8以后,永久存储区改了个名字(元空间) 在这里插入图片描述图 堆内存溢出
新生区、老年区
新生区
●类:诞生和成长的地方,甚至死亡;
●伊甸园,所有的对象都是在伊甸园区new出来的!
如果对象过大,会直接丢到老年代
图 重GC和轻GC
伊甸园满了就触发轻GC,经过轻GC存活下来的就到了幸存者区,幸存者区满之后意味着新生区也满了,则触发重GC,经过重GC之后存活下来的就到了养老区。
真理:经过研究,99%的对象都是临时对象!
永久区
这个区域常驻内存,用来存放JDK自身携带的Class对象。Interface元数据,存储是Java运行时的一些环境或类信息。这个区域不存在垃圾回收。关闭VM虚拟就会释放这个区域的内存~
一个启动类,加载了大量的第三方jar包。
jdk1.6之前:永久代,常量池是在方法区;
jdk1.7 永久代,但是慢慢的退化了,去永久代,常量池在堆中。
jdk1.8之后:无永久代,常量池在元空间!
图 JVM探究
元空间:逻辑上存在,物理上不存在 (因为存储在本地磁盘内) 所以最后并不算在JVM虚拟机内存中
网友评论