永久代VS元空间

永久代VS元空间

HotSpot虚拟机的内存模型

如图,了解一下:

img

官方对方法区的介绍

方法区在JDK1.7及其以前版本中的实现方式——永久带在JKD8中被移除了。

在 Java 虚拟机中,方法区( Method Area) 是可供各条线程共享的运行时内存区域。方法区与传统语言中的编译代码储存区( Storage Area Of Compiled Code)或者操作系统进程的正文段( Text egment)的作用非常类似,它存储了每一个类的结构信息,例如运行时常量池( Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法。

方法区在虚拟机启动的时候被创建,虽然方法区是堆的逻辑组成部分,但是简单的虚拟机实现可以选择在这个区域不实现垃圾收集。这个版本的 Java 虚拟机规范也不限定实现方法区的内存位置和编译代码的管理策略。方法区的容量可以是固定大小的,也可以随着程序执行的需求动态扩展,并在不需要过多空间时自动收缩。方法区在实际内存空间中可以是不连续的。

Java 虚拟机实现应当提供给程序员或者最终用户调节方法区初始容量的手段,对于可以动态扩展和收缩方法区来说,则应当提供调节其最大、最小容量的手段。

总之,就是用来存储类的描述信息——元数据的。它有一个别名叫做Non-Heap(非堆)。

常说的永久代和方法区是什么关系

平时,说到永久带(PermGen space)的时候往往将其和方法区不加区别。这么理解在一定角度也说的过去。
因为,《Java虚拟机规范》只是规定了有方法区这么个概念和它的作用,并没有规定如何去实现它。那么,在不同的 JVM 上方法区的实现肯定是不同的了。
同时,大多数用的JVM都是Sun公司的HotSpot。在HotSpot上把GC分代收集扩展至方法区,或者说使用永久带来实现方法区。

虽然可以牵强的解释这种将方法区和永久带等同对待观点。但最终方法区和永久带还是不同的。一个是标准一个是实现。这就相当于你将java中的接口和接口的实现等同对待了一样。
同时,这种牵强的解释也仅仅是在HotSpot虚拟机上才能勉强成立。其他的虚拟机实现并没有永久带这一说法。
有人说,HotSpot之所以用永久带来实现方法区是因为这样可以不必专门为方法区编写一套内存管理的代码。

大小调节

在1.7之前,可以使用如下参数来调节方法区的大小

//方法区初始大小
-XX:PermSize

// 方法区最大大小, 超过这个值将会抛出OutOfMemoryError异常:java.lang.OutOfMemoryError: PermGen
-XX:MaxPermSize

jdk8中的方法区

在jdk8中已经将永久带移除了。也就是说-XX:PermSize这些参数在jdk8中将是无效的。
移除了,肯定有人来代替他。就是新出现的元空间(Metaspace)来代替原来的永久带。

方法区中主要存放的是一些描述性信息,即元数据。

方法区是堆的逻辑组成部分。实际上JDK1.7中,存储在永久代的部分数据就已经转移到了Java Heap或者是 Native Heap。但永久代仍存在于JDK1.7中,但是并没完全移除。

大小调节

在1.8中,使用如下参数来调节方法区的大小

//元空间初始大小
-XX: MetaspaceSize

// 元空间最大大小, 超过这个值将会抛出OutOfMemoryError异常:java.lang.OutOfMemoryError: Metadata space
-XX: MaxMetaspaceSize
<think>好的,我需要帮助用户理解Java内存模型中的新生、老年永久空间的区别与联系。首先,我应该根据提供的引用资料,整理出每个区域的基本概念和功能。 首先,新生和老年都属于Java堆的一部分,这点在引用3中提到过。新生又分为Eden、From Survivor和To Survivor区,主要存放新创建的对象。当对象经过多次GC仍然存活,就会晋升到老年,如引用1和4所述。老年用于存放长期存活的对象和大对象,当新生空间不足时也会直接分配到这里,引用4还提到老年GC的条件。 接下来是永久空间。根据引用2,永久是方法区的实现,在JDK8之前存在,容易导致OOM错误。而空间是JDK8引入的,使用本地内存,避免了永久的问题,如引用2所述。空间存放类数据等信息,而永久在堆内存中。 然后需要比较它们的区别和联系。内存位置方面,新生和老年在堆中,永久以前在堆,空间在本地内存。存放内容方面,新生放新对象,老年放长期存活对象,永久空间放类数据。垃圾回收方面,新生使用Minor GC,老年用Major GC,永久空间的回收机制不同,空间更灵活。 最后,可能用户还会想知道为什么用空间永久,以及各个区域的GC触发条件。例如引用4提到老年GC可能在新生GC后触发,或者大对象分配失败时触发。引用5给出了新生各区的具体内存分配例子,这可以帮助用户更直观地理解大小比例。 需要确保回答结构清晰,分点说明每个区域,然后总结区别与联系。同时要正确引用资料中的信息,比如引用1提到对象晋升的条件,引用2说明空间的优势,引用3的结构划分,引用4的GC触发条件,引用5的内存大小示例。在回答过程中自然添加引用标识,避免使用Markdown格式,保持口语化但专业。</think>### Java内存区域划分详解(新生/老年/永久/空间) #### 一、核心概念解析 1. **新生** 新创建对象的初始分配区域,分为$Eden$区(占80%)和两个$Survivor$区(各占10%)。当$Eden$区满时触发**Minor GC**,存活对象移动到$Survivor$区,经过多次回收(默认15次)仍存活的对象晋升到老年[^1][^3]。 ```java // 示例:通过JVM参数设置新生大小 -XX:NewSize=256m // 初始新生大小 -XX:MaxNewSize=1024m // 最大新生大小 ``` 2. **老年** 存放长期存活对象和大对象(如超过$Eden$区大小的数组)。当老年空间不足时触发**Major GC**(通常伴随Full GC),回收效率低于Minor GC[^4][^1]。 *触发条件示例*: - 新生对象晋升失败 - 大对象直接分配请求(如`new byte[10MB]`) - 空间分配担保失败(`HandlePromotionFailure`策略) 3. **永久(JDK≤7)** 方法区的具体实现,存储类数据、常量池等信息。由于固定大小易导致`PermGen space`错误,最大仅能设置到82MB(32位JVM)或4GB(64位JVM)[^2]。 4. **空间(JDK≥8)** 替永久,使用本地内存(非JVM堆),默认无上限。通过`-XX:MaxMetaspaceSize`可限制大小,有效避免内存溢出[^2]。 #### 二、关键区别对比 | 特性 | 新生/老年 | 永久 | 空间 | |--------------|------------------------------|---------------------|-----------------------| | **存储位置** | Java堆内存 | Java堆内存(JDK7-) | 本地内存(JDK8+) | | **存储内容** | 对象实例 | 类数据、常量池 | 类数据 | | **GC机制** | 分收集(Minor/Major GC) | Full GC时回收 | 独立内存管理系统 | | **溢出表现** | `OutOfMemoryError: Java heap`| `PermGen space`错误 | 本地内存耗尽才会OOM | #### 三、内存结构示意图 ``` Java内存区域 ├── 堆(Heap) │ ├── 新生(Young Generation) │ │ ├── Eden区(新对象分配区) │ │ ├── Survivor From(GC存活对象暂存) │ │ └── Survivor To(年龄计数器递增) │ └── 老年(Old Generation) └── 非堆内存 ├── 方法区(Method Area) │ ├── 永久(JDK7-,已废弃) │ └── 空间(JDK8+,本地内存) └── 其他(PC寄存器、JVM栈等) ``` #### 四、实践建议 1. **监控工具** 使用`jstat -gc <pid>`观察各区内存变化,例如: ```bash jstat -gc 12345 1000 # 每1秒打印进程12345的GC情况 ``` 输出示例: ``` S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 2048.0 2048.0 0.0 0.0 16384.0 8192.0 40960.0 20480.0 4864.0 3648.0 512.0 384.0 5 0.123 1 0.456 0.579 ``` 2. **参数调优** - 新生与老年比例:`-XX:NewRatio=2`(老年:新生=2:1) - Survivor区比例:`-XX:SurvivorRatio=8`(Eden:Survivor=8:1:1) - 空间限制:`-XX:MaxMetaspaceSize=256m`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值