为什么用元空间替代永久代?

Crq
Crq
管理员
1440
文章
0
粉丝
Linux教程评论3字数 900阅读3分0秒阅读模式
摘要永久代和元空间都是 HotSpot 虚拟机中的概念,HotSpot 虚拟机是 Sun JDK 和 Open JDK 中自带的虚拟机,也是目前使用范围最广泛的 Java 虚拟机,当我...
1.官方答案

关于这个问题,官方在 JEP 122: Remove the Permanent Generation(移除永久代)中给出了答案,原文内容如下:

Motivation(动机)
This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.

以上内容翻译成中文大意是:

这是 JRockit 虚拟机和 HotSpot 虚拟机融合工作的一部分。JRockit 客户不需要配置永久层代(因为 JRockit 没有永久代),所以要移除永久代。

JRockit 是 Java 官方收购的一家号称史上运行最快的 Java 虚拟机厂商,之后 Java 官方在 JDK 8 时将 JRockit 虚拟机和 HotSpot 虚拟机进行了整合。

PS:JEP 是 JDK Enhancement Proposal 的缩写,翻译成中文是 JDK 改进提案。你也可以把它理解为 JDK 的更新文档。
通过官方的描述,我们似乎找到了答案,也就是说,之所以要取消“永久代”是因为 Java 官方收购了 JRockit,之后在将 JRockit 和 HotSpot 进行整合时,因为 JRockit 中没有“永久代”,所以把永久代给移除了。

PS:上面的那段描述好像说的已经很清楚了,但又好像什么也没说。这就好比,我问你“为什么要买车?”,你说“别人都买车了,所以我要买车”,但为什么别人要买车?

2.背后的原因

上述给出了移除永久代的回答,但却没有给出背后的原因,那接下来我们就来讨论一下,为什么要移除永久代?以及为什么要有元空间?

2.1 降低 OOM

当使用永久代实现方法区时,永久代的最大容量受制于 PermSize 和 MaxPermSize 参数设置的大小,而这两个参数的大小又很难确定,因为在程序运行时需要加载多少类是很难估算的,如果这两个参数设置的过小就会频繁的触发 FullGC 和导致 OOM(Out of Memory,内存溢出)。

但是,当使用元空间替代了永久代之后,出现 OOM 的几率就被大大降低了,因为元空间使用的是本地内存,这样元空间的大小就只和本地内存的大小有关了,从而大大降低了 OOM 的问题。

2.2 降低运维成本

因为元空间使用的是本地内存,这样就无需运维人员再去专门设置和调整元空间的大小了。

3.方法区发展史

在 HotSpot 虚拟机中,方法区的实现经历了以下 3 个阶段:

JDK 1.6 及之前:方法区使用永久代实现,静态变量存放在永久代;
JDK 1.7 :“去永久代”的前置版本,还存在永久代,不过已经将字符串常量池和静态变量从永久代移到了堆上;
JDK 1.8 及以后:无永久代,使用元空间(存放在本地内存中)实现方法区,常量保存在元空间,但字符串常量池和静态变量依然保存在堆中。

总结

永久代和元空间都是 HotSpot 虚拟机对《Java 虚拟机规范》中方法区的实现,在 JDK 1.8 之前 HotSpot 是使用永久代来实现方法区的,但这样会导致 JVM 调优比较困难,且容易发生 OOM 的问题,而 JDK 1.8 及之后,使用的是元空间存放在本地内存中的方式来替代永久代的,这样就降低了 OOM 发生的可能性,也是 JRockit 和 HotSpot 融合之后的改动之一。

weinxin
我的微信
微信号已复制
我的微信
这是我的微信扫一扫
 
Crq
  • 本文由 Crq 发表于2025年1月19日 00:09:22
  • 转载请注明:https://www.cncrq.com/12666.html
Linux -mv命令的10个实用例子 Linux教程

Linux -mv命令的10个实用例子

mv 命令是一个与cp类似的命令,但是它并非创建文件或目录的复制品/副本。不管你在使用什么版本的Linux系统,mv 都默认安装在你的Linux系统上了。来看一下 mv 命令在日常...
JVM 如何确定死亡对象? Linux教程

JVM 如何确定死亡对象?

在 JVM 中,有两个非常重要的知识点,一个是 JVM 的内存布局(JVM 运行时的数据区域),另一个就是垃圾回收。而垃圾回收中又有两个重要的知识点,一个是如何确定 JVM 中的垃...
CentOS 7.3 安装指南 Linux教程

CentOS 7.3 安装指南

基于 Red Hat 企业版的源代码的最新版本的 CentOS 7 在今年的 12月发布了 CentOS Linux 7 (1611) ,包含了许多 bug 修复、新的包更新,比如...
Linux 上的 MAC 地址欺骗 Linux教程

Linux 上的 MAC 地址欺骗

网卡生产商在每一张网卡(NIC)在出厂时都会在上面刻上一个48位的全球唯一标识符(GUID),这串 GUID 就是网卡的 MAC 地址,用于确定一张网卡的身份。MAC 地址的高24...
匿名

发表评论

匿名网友
:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:
确定

拖动滑块以完成验证