justtreee / blog

31 stars 8 forks source link

【Java】《深入理解Java虚拟机》笔记 · 一 Java内存区域 #11

Open justtreee opened 6 years ago

justtreee commented 6 years ago

一. Java内存区域

原书第二章

1. 运行时区域

原书2.2节

书上讲的很难理解,这里有一张图:Link1

jvm

如果想查阅书上原文(P38-43),这篇博客 整理的很好。

2. 方法区和运行时常量池溢出

原书2.4.3节

书中进行了一个String.intern()返回引用的测试。 分别在JDK1.6和JDK1.7分别运行会产生不同的结果。产生差异的原因:JDK1.6中,intern()方法会把首次遇到的字符串实例复制到永久代上,返回的就是永久代上的实例引用,而StringBuilder创建的字符串实例在java堆上,所以两者不会是一个引用。

而在JDK1.7上intern()只是在常量池中记录首次出现的实例引用,也就是和StringBuilder创建的实例是同一个。

PermGen(永久代) 这里的 “PermGen space”其实指的就是方法区。不过方法区和“PermGen space”又有着本质的区别。前者是 JVM 的规范,而后者则是 JVM 规范的一种实现,并且只有 HotSpot 才有 “PermGen space”,而对于其他类型的虚拟机,如 JRockit(Oracle)、J9(IBM) 并没有“PermGen space”。由于方法区主要存储类的相关信息,所以对于动态生成类的情况比较容易出现永久代的内存溢出。最典型的场景就是,在 jsp 页面比较多的情况,容易出现永久代内存溢出。

Metaspace(元空间) 在 JDK 1.8 中, HotSpot 已经没有 “PermGen space”这个区间了,取而代之是一个叫做 Metaspace(元空间) 的东西。 元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。

参考链接

《深入理解Java虚拟机》读书笔记 《深入理解Java虚拟机》读书笔记1:Java技术体系、Java内存区域和内存溢出异常 《Java虚拟机原理图解》3、JVM运行时数据区 JVM内存结构---《深入理解Java虚拟机》学习总结 Java8内存模型—永久代(PermGen)和元空间(Metaspace)