关于jvm中的方法区和常量池问题

本文详细介绍了JDK1.8前后方法区的变化,包括1.8前后的不同特性及其带来的影响。重点讲解了1.8之后引入的元空间如何替代方法区,并解决了内存溢出的问题。

1:方法区:
首先这个问题要分jdk:
1.8之前是独立的,里面只要是装着类的信息,代码和静态变量。
方法区和堆的物理存储是连接在一块的,但是这种做法会出现一些问题,程序中加载的jar包和类过多的话,就会出现啊oom(内存溢出)的错误。
1.8之后:方法区不存在的,但是多了一个元空间,他就是用来代替方法区的,但是元空间和堆在物理空间上是隔离的,虽然性能降低了,但是解决了oom问题,元空间的地址不是jvm地址而是你的电脑本地内存,只要你的本地内存充足,就可以一直运行。
2:常量池
1.8之前常量池在方法区中,但是1.8之后就是存在于堆内存之中了。
原因有两个:
1:堆内存回收效率高
2:元空间一般是不会设置太大的值,可以避免oom.

### 方法区的作用与特性 方法区JVM 内存结构中的一部分,主要用于存储类的元数据信息。这些信息包括类的名称、访问修饰符、字段描述、方法描述、静态变量以及编译器生成的字节码等[^1]。在 Java 虚拟机规范中,方法区被描述为堆的一个逻辑部分,但它具有独立的用途生命周期。 #### 作用 - **存储类元数据**:方法区保存了每个类的基本信息,如类名、父类名、接口列表、方法表等。 - **运行时常量池**:每个类或接口的常量池都会被加载到方法区中的运行时常量池。 - **静态变量**:类级别的静态变量也被存储在方法区中。 - **编译器优化支持**:一些即时编译器(JIT)会利用方法区中的数据来进行优化。 #### 特性 - **线程共享**:方法区是所有线程共享的内存区域。 - **非堆内存**:虽然方法区通常实现为堆的一部分,但它是独立管理的,并且可以有自己特定的垃圾回收策略。 - **可选GC**:Java 虚拟机规范不要求对方法区进行垃圾收集,但在实际应用中,某些 JVM 实现可能会对无用的类常量进行清理。 ### 运行时常量池的作用与特性 运行时常量池方法区的一部分,它包含了编译期间确定的各种字面量符号引用。此外,还可以包含动态链接所需的信息。 #### 作用 - **存储常量**:包括字符串常量、数值常量以及其他类型的常量。 - **符号引用**:用于解析类、接口、方法字段的符号名称到直接引用的过程。 - **动态链接**:支持类间的动态连接,使得类可以在运行时解析其他类的方法字段。 #### 特性 - **动态性**:除了编译期产生的常量外,运行时常量池还支持运行时动态添加新的常量,例如通过 `String.intern()` 方法。 - **高效访问**:为了提高性能,JVM 会对运行时常量池进行优化,以加快常量的查找速度。 ### 区别与联系 | 特征 | 方法区 | 运行时常量池 | |------|--------|--------------| | **位置** | JVM 内存结构中的一个独立区域 | 属于方法区的一部分 | | **主要功能** | 存储类的元数据信息 | 存储编译期产生的常量符号引用 | | **生命周期** | 类加载时创建,类卸载时销毁 | 伴随类的加载而创建,类卸载时销毁 | | **是否线程安全** | 是,所有线程共享 | 是,作为方法区的一部分也是线程共享的 | ### 示例代码:查看运行时常量池 以下是一个简单的示例,演示如何使用 `String.intern()` 来向运行时常量池中添加字符串: ```java public class ConstantPoolExample { public static void main(String[] args) { String str1 = new StringBuilder("Ja").append("va").toString(); System.out.println(str1.intern() == str1); // 输出 true 或 false 取决于 JVM 实现 String str2 = new StringBuilder("He").append("llo").toString(); System.out.println(str2.intern() == str2); // 同样输出 true 或 false } } ``` 此代码展示了 `intern()` 方法的行为,该方法尝试将字符串实例加入到运行时常量池中并返回其引用。需要注意的是,不同 JVM 实现可能对此行为有不同的处理方式。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值