java8和java7运行时数据区域的区别
1 运行时数据区域
Java7中运行时数据区域有:Java堆、方法区、程序计数器、虚拟机栈、本地方法栈。
Java8(Hotspot)中把方法区永久删除了,取而代之的是元空间,使用的是直接内存。
2 为什么方法区会被叫做永久代
《Java 虚拟机规范》只是规定了有方法区这么个概念和它的作用,并没有规定如何去实现它。那么,在不同的 JVM 上方法区的实现肯定是不同的了。 方法区和永久代的关系很像 Java 中接口和类的关系,类实现了接口,而永久代就是 HotSpot 虚拟机对虚拟机规范中方法区的一种实现方式。 也就是说,永久代是 HotSpot 的概念,方法区是 Java 虚拟机规范中的定义,是一种规范,而永久代是一种实现,一个是标准一个是实现,其他的虚拟机实现并没有永久代这一说法。
3 原因
首先看一下移除永久代前后调整方法区大小所设置的参数:
jdk1.8之前:
-XX:PermSize=N // 方法区 (永久代) 初始大小
-XX:MaxPermSize=N // 方法区 (永久代) 最大大小,超过这个值将会抛出 OutOfMemoryError 异常:java.lang.OutOfMemoryError: PermGen
jdk1.8之后:
-XX:MetaspaceSize=N //设置 Metaspace 的初始(和最小大小)
-XX:MaxMetaspaceSize=N //设置 Metaspace 的最大大小
看似好像没多大区别,其实元空间和永久代一个很大不同是如果不指定大小,随着更多类的创建,虚拟机会耗光所有可用的系统内存。
- 整个永久代有一个JVM本身设置的固定大小上下限,无法进行调整,而元空间使用的是直接内存,受本机可用内存的限制,然后元空间仍可能存在溢出,但几率比之前小了很多。
- 能加载的类更多了,因为它存放的是类的元数据。
- 在 JDK8,合并 HotSpot 和 JRockit 的代码时, JRockit 从来没有一个叫永久代的东西, 合并之后就没有必要额外的设置这么一个永久代的地方了。