方法区、永久代、元空间的关系

什么是方法区、永久代、元空间

众所周知,方法区是运行时数据区很重要的一部分,是用来存储类的信息、常量池、方法数据、及时编译器编译的代码等。

永久代是jdk1.7之前对方法区的一个落地实现,存在于堆中,用于存储类的信息和字符串常量池,同样包含SE库的类和方法。在jdk1.7时将字符串常量池从永久代移动到堆中,永久代在jdk8被移除。

元空间和永久代类似,都是对方法区的一个落地实现,他里面存储的数据比永久代纯粹很多,就是类的元数据。元空间的位置不存在于虚拟机中,而是在本地内存中。

为什么以元空间取代永久代

永久代的缺点

  1. 占用了堆的空间
  2. 永久代空间太大占用过多堆内存,太小存储类信息有限
  3. 永久代的 GC 会触发堆的 GC

为什么之前可以这么设计?

当时还是32位机,并看的不是很清楚,到现在64位机,弊端就暴露出来。

元空间解决了永久代的问题,jdk1.8起开始取代永久代存放类信息

元空间存在的问题

元空间是按照类加载器分配空间的,也就是说类加载器加载了一个类,元空间分配给这个类的空间其实是分配给的类加载器,不同的类加载器占用不同的空间,它们之间不共享类信息,如果程序中有大量的类加载器,而它们加载的类非常少,那么有可能会造成大量的空间浪费。

空间分隔开也久可能会造成内存空间碎片化。

### Java 空间方法区关系及区别 #### 方法区的概念 方法区是《Java虚拟机规范》中定义的一个逻辑区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的码等数据。不同的虚拟机实现可能会采用不同的方式来具体实现这一抽象概念。 #### 永久的历史背景 在JDK 7及其之前版本中,HotSpot虚拟机使用了一种名为“永久”的内存模型来实现方法区的功能[^4]。这种设计允许垃圾回收机制如同对待堆中的对象一样处理这些数据,简化了内存管理和优化工作。 #### 空间的新特性 自JDK 8起,为了更好地适应现硬件架构并提高性能表现,HotSpot VM引入了一个新的运行时组件——空间(Metaspace)[^1]。相比于之前的永久: - **位置差异**:空间位于本地内存(Native Memory)而非传统的Java堆内;这减少了GC压力,并且避免了由于频繁调整堆尺寸带来的开销。 - **灵活性增强**:不再受限于固定大小,可根据实际需求自动增长或收缩其容量范围; - **配置变化**:原有的针对永久设置的相关参数已失效,转而提供了专门控制空间行为的新选项[^3]。 因此,在JDK 8之后,“空间”成为了HotSpot JVM内部对于方法区的具体实现形式之一,取了早期版本中存在的“永久”。 ```java // 示例展示如何查看当前使用的空间大小 public class MetaspaceExample { public static void main(String[] args) throws Exception{ RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); List<String> arguments = runtimeMxBean.getInputArguments(); boolean isMetaspaceUsed = false; for (String arg : arguments){ if(arg.startsWith("-XX:MaxMetaspaceSize=")){ System.out.println("Current Max Metaspace Size:" + arg.substring(20)); isMetaspaceUsed=true; } } if(!isMetaspaceUsed){ System.out.println("Default Metaspace size will be used."); } } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值