java8的元空间到底存储了什么?

java8中移除了永久带,新增了元空间的概念。JVM加载类的时候,需要记录类的元数据,这些数据会保存在一个单独的内存区域中,在java7里,这个空间被称为永久代,在java 8里,使用元空间代替了永久代。永久代和元空间保存的数据并不完全一样,永久代还保存另一些与类的元数据无关的杂项。

在java7里,将字符串常量从永久代移到了堆区域,但是永久代并没有完全改造完成。直到java 8,永久代的改造才算完全搞定,在元空间中保存的数据比永久代纯粹的多,就是类的元数据,这些信息只对编译器或JVM的运行时才有用。

在java8中,符号引用存储在native heap中,字符串常量和静态类型变量存储在普通的堆区中。

### Java 8 Metaspace 使用与配置 从 JDK 8 开始,永久代(PermGen)被废弃,取而代之的是空间(Metaspace)。空间使用本地内存而非堆内存,其大小默认情况下仅受系统可用的本地内存限制。然而,用户可以通过特定参数对空间进行控制和优化[^1]。 #### 空间的基本概念 空间主要用于存储类的信息,包括类的字节码、常量池、字段和方法数据等。相比永久代,空间的一个显著优势是不再受限于固定大小的堆内存区域,从而减少了因类加载过多而导致的 `java.lang.OutOfMemoryError: PermGen` 问题的发生几率[^2]。 #### 默认行为与调整参数 尽管引入了空间,但并不意味着内存泄漏或 OutOfMemoryError 的问题会完全消失。如果应用程序频繁加载和卸载大量类,仍然可能出现内存不足的情况。因此,合理调整空间的大小至关重要[^3]。 以下是常用的空间调整参数: - **-XX:MetaspaceSize**:设置初始空间大小。当达到此值时,JVM 会触发一次 Full GC,并尝试减少空间占用。 - **-XX:MaxMetaspaceSize**:设置空间的最大大小。若未显式指定,则空间将一直增长直到耗尽本地内存。 - **-XX:MinMetaspaceFreeRatio** 和 **-XX:MaxMetaspaceFreeRatio**:用于控制 Full GC 后空间的空闲比例。 例如,以下是一个典型的配置示例: ```bash java -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -jar application.jar ``` #### 调优建议 1. **监控空间使用情况**:通过工具如 `jstat` 或 `VisualVM` 查看空间的实际使用情况。例如,使用以下命令可以查看空间的统计信息: ```bash jstat -gc <pid> ``` 其中 `<pid>` 是目标 Java 进程的 ID[^4]。 2. **根据实际需求调整大小**:如果发现空间频繁接近上限,应适当增加 `-XX:MaxMetaspaceSize` 的值;反之,若空间长期未充分利用,则可降低该值以节省资源。 3. **避免类加载导致的内存泄漏**:即使使用了空间,仍需注意可能导致内存泄漏的场景,例如动态代理或频繁重新加载类[^2]。 #### 示例代码 以下是一个简单的 Java 程序,演示如何通过命令行参数设置空间大小并观察其行为: ```java public class MetaspaceExample { public static void main(String[] args) { try { while (true) { ClassLoader loader = new java.net.URLClassLoader(new java.net.URL[]{}); loader.loadClass("NonExistentClass"); } } catch (Exception e) { System.out.println("Metaspace exhausted!"); } } } ``` 运行时可以指定不同的空间大小参数来测试程序的行为。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值