别再说不知道元空间和永久代的区别了

java8来临之前的永久代

永久代:用来存储类的编译信息,常量、和静态变量
在这里插入图片描述
堆和方法去逻辑上是分开的,但是在物理内存上两者又是连续的
在精确一些,实际上是
在这里插入图片描述
方法区和老年代是相连的,所以永久代的垃圾收集是和老年代捆绑在一起的,因此无论谁满了,都会触发永久代和老年代的垃圾收集。

经历变迁
在Java7中永久代中存储的部分数据已经开始转移到Java
Heap或Native Memory(本地内存)中了。比如,符号引用(Symbols)转移到了Native Memory;字符串常量池(interned
strings)转移到了堆;类的静态变量(class statics)转移到了堆。然后,在Java8中,Hotspot jdk取消了永久代。永久代的参数-XX:PermSize和-XX:MaxPermSize也随之失效。随之而来的是元空间

经历时间洗礼后的元空间

对于Java8,HotSpots取消了永久代,那么是不是就没有方法区了呢?
当然不是,方法区只是一个规范,只不过它的实现变了。在Java8中,元空间(Metaspace)登上舞台,方法区存在于元空间(Metaspace)。同时,元空间不再与堆连续,而且是存在于本地内存(Native memory,也称作直接内存)

了解一下本地内存
在这里插入图片描述

本地内存(Native memory),也称为C-Heap,是供JVM自身进程使用的。当Java Heap空间不足时会触发GC,但Native memory空间不够却不会触发GC

那元空间保存在本地内存中的好处是什么呢?
==原因一:==因为直接内存,JVM将会在IO操作上具有更高的性能,因为它直接作用于本地系统的IO操作。而非直接内存,也就是堆内存中的数据,如果要作IO操作,会先复制到直接内存,再利用本地IO处理。
从数据流的角度,非直接内存是下面这样的作用链:本地IO --> 直接内存 --> 非直接内存 --> 直接内存 --> 本地IO

而直接内存是:本地IO --> 直接内存 --> 本地IO
==原因二:==整个永久代有一个 JVM 本身设置固定大小上线,无法进行调整,而元空间使用的是直接内存,受本机可用内存的限制,并且永远不会得到java.lang.OutOfMemoryError。

设置元空间大小
可以使用 -XX:MaxMetaspaceSize 标志设置最大元空间大小,默认值为 unlimited,这意味着它只受系统内存的限制。
-XX:MetaspaceSize 调整标志定义元空间的初始大小如果未指定此标志,则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小。

猜你喜欢

转载自blog.csdn.net/qq_41700030/article/details/108323758
今日推荐