Java1.8开始为什么用元空间替换永久代

本文介绍了从Java 1.8开始,JDK中永久代被元空间替代的过程,并详细解释了元空间与方法区的关系,以及如何通过参数配置元空间大小。

一 概述

Java1.8开始,JDK中的永久代被元空间替换了。

二 回顾JMM中的方法区

如图所示,方法区同堆空间一样,属于所有线程共享的数据区域,它用于存储已经被虚拟机加载的类信息,常量,静态变量,即时编译后的代码等数据。

三 回顾永久代与方法区的关系

如果在HotSpot虚拟机上开发,部署,方法区是规范,永久代是Hotspot针对该规范进行的实现。在Java7及以前的版本中,方法区都是永久代实现的。

四 元空间与方法区的关系

对于Java8而言,HotSpots取消了永久代,取而代之的是元空间(Metaspace),换言之,就是方法区是在的,只是实现方式由原来的永久代变成了现在的元空间了。

多版本JDK中的参数信息

五 使用元空间替换永久代的原因

如图所示,永久代的方法区和堆使用的物理内存是连续的。

永久代的大小配置

  • -XX:PermSize:设置永久代的初始大小。
  • -XX:MaxPermSize:设置永久代的最大值,默认是64M。

对于永久代,如果动态生成很多class的时候,很有可能出现java.lang.OutOfMemoryError:PermGen space错误,这是因为永久代空间配置的大小有限。

在典型的单一应用中,需要编写和加载很多的jsp页面,就会出现java.lang.OutOfMemoryError。

在JDK1.8版本之后,方法区存在于元空间(Metaspace)。物理内存不再与堆连续,而是直接存在于本地内存中,理论上,机器内存有多大,元空间就有多大。

基于上图可知,元空间存在于本地内存中,我们可以通过一些参数对元空间的大小进行配置:

  • -XX:MetaspaceSize:初始空间大小,达到这些值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整;如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
  • -XX:MaxMetaspaceSize:最大空间,默认是没有限制的。
  • -XX:MinMetaspaceFreeRatio:在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集。
  • -XX:MaxMetaspaceFreeRatio:在GC之后,最大的Metasapce剩余空间容量的百分比,减少为释放空间锁导致的垃圾收集。

综上所述,表面上是为了避免OOM异常,因为通常使用PermSize和MaxPermSize设置了永久代的大小上限,但是不是总能设置到刚刚合适的大小,而使用默认值是很容易遇到OOM错误。当使用元空间时,可以加载多少类的元数据就不再由MaxPermSize控制,而是由系统的实际可用空间来控制。

### 如何下载和配置 Java 1.8 JDK #### 下载 Java 1.8 JDK 为了获取适用于系统的 Java Development Kit (JDK) 版本 1.8,访问 Oracle 官方网站上的 Java SE 下载页面[^2]。该网页提供了多种操作系统对应的安装包选项,包括 Windows、Linux 和 macOS。 对于 **Windows 用户**: - 访问 [Oracle 官网](https://www.oracle.com/java/technologies/javase-jdk8-downloads.html),找到适合操作系统的 JDK 1.8 版本链接并点击下载按钮。 对于 **macOS 用户**: - 同样前往上述网址,在 Mac OS X 部分选择合适的 .dmg 文件进行下载[^4]。 完成下载之后,按照提示执行安装程序,默认设置通常能满足大多数需求;如果有特殊要求,则可根据实际情况调整安装位置等参数。 #### 配置环境变量 ##### 设置 `JAVA_HOME` 在命令行工具中输入以下指令来设定永久性的 JAVA_HOME 变量(具体路径需替换为实际安装目录): 对于 **Windows 用户**: 通过系统属性 -> 高级系统设置 -> 环境变量 来添加新的系统变量名为 `JAVA_HOME` 并将其值设为 JDK 的根目录,例如 `D:\Programmer\ProgrammerUtil\JDK\JDK1.8\jdk1.8.0_77`[^3]。 对于 **macOS/Linux 用户**: 编辑 `.bash_profile` 或者 `.zshrc` 文件,加入如下行: ```shell export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home ``` 保存更改后运行 `source ~/.bash_profile` 或 `source ~/.zshrc` 使新设置生效。 ##### 更新 `PATH` 接着更新 PATH 路径以便可以直接调用 javac 和 java 命令。继续在同一文件里追加下面的内容: ```shell export PATH=$JAVA_HOME/bin:$PATH ``` 这一步骤同样适用于所有平台,只需确保 `$JAVA_HOME` 正确指向了之前定义的位置。 ##### (可选)配置 `CLASSPATH` 虽然现开发实践中很少手动指定 CLASSPATH,但如果项目有特定依赖关系可能仍有必要这样做。可以像这样扩展之前的脚本: ```shell export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ``` 注意这里的冒号表示当前工作目录也应被纳入类加载器考虑范围之内。 最后重启终端窗口或重新登录以应用这些修改后的环境变量设置。 验证安装是否成功的最简单方法是在命令行输入 `java -version` 和 `javac -version`,如果返回的是关于已安装的 JDK 1.8 的信息则说明一切正常[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值