HotSpot和堆

2020-10-25  本文已影响0人  笨比乔治

三种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出来的!
如果对象过大,会直接丢到老年代

●幸存者区(0,1) 在这里插入图片描述

图 重GC和轻GC

伊甸园满了就触发轻GC,经过轻GC存活下来的就到了幸存者区,幸存者区满之后意味着新生区也满了,则触发重GC,经过重GC之后存活下来的就到了养老区。
真理:经过研究,99%的对象都是临时对象!

永久区

这个区域常驻内存,用来存放JDK自身携带的Class对象。Interface元数据,存储是Java运行时的一些环境或类信息。这个区域不存在垃圾回收。关闭VM虚拟就会释放这个区域的内存~
一个启动类,加载了大量的第三方jar包。
jdk1.6之前:永久代,常量池是在方法区;
jdk1.7 永久代,但是慢慢的退化了,去永久代,常量池在堆中。
jdk1.8之后:无永久代,常量池在元空间!

image.png image.png

图 JVM探究

元空间:逻辑上存在,物理上不存在 (因为存储在本地磁盘内) 所以最后并不算在JVM虚拟机内存中

上一篇下一篇

猜你喜欢

热点阅读