温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java元空间怎么理解

发布时间:2026-10-30 16:53:54 来源:亿速云 阅读:96 作者:小樊 栏目:编程语言

在 Java 里,**元空间(Metaspace)**是 JVM 用来存储“类元数据”的内存区域,从 JDK 8 开始取代原来的 永久代(PermGen)。

下面用「是什么 → 存什么 → 为什么改 → 怎么调 → 常见问题」来理解。


一、什么是元空间(Metaspace)

Metaspace 是 JVM 的一块本地内存(Native Memory),不属于 Java 堆(Heap)。

  • JDK 7 及以前:类信息放在 永久代(PermGen,在堆里)
  • JDK 8 及以后:类信息放在 元空间(Metaspace,在本地内存)

简单说:
元空间 = 存放“类本身信息”的地方


二、元空间里存什么?

主要包括:

  • 类的结构信息
    • 类名、父类、接口
    • 字段、方法定义
  • 方法字节码
  • 常量池(部分)
  • 注解信息
  • 静态变量(注意:JDK 8 后静态变量在堆里,不在元空间)

✅ 不包括:

  • 对象实例(在堆)
  • 局部变量(在栈)

三、为什么用元空间取代永久代?

永久代的问题

  1. 大小固定,容易 OOM
    java.lang.OutOfMemoryError: PermGen space
    
  2. 调优困难(和堆耦合)
  3. 类卸载不彻底时容易溢出

元空间的优势

✅ 使用 本地内存 ✅ 默认只受本机内存限制 ✅ 动态扩容,不容易轻易 OOM ✅ 类元数据管理更合理


四、元空间内存模型(重点)

1️⃣ 组成结构

Metaspace 分为:

  • Class Metaspace:存类元数据
  • Non-Class Metaspace:存其它元数据(如 intern 字符串等)

2️⃣ 内存分配单位

  • 以 Chunk(内存块) 分配
  • 多个类共享 Chunk
  • 类卸载后 Chunk 可复用

五、常用 JVM 参数(很重要)

# 初始元空间大小
-XX:MetaspaceSize=64m

# 最大元空间大小(防止无限膨胀)
-XX:MaxMetaspaceSize=256m

# 达到该值触发 GC(类卸载)
-XX:MetaspaceSize

⚠️ 如果不设置 MaxMetaspaceSize,可能撑爆物理内存


六、典型 OOM 场景

1️⃣ 动态生成类过多

例如:

  • 大量使用 CGLIB / ByteBuddy
  • 热部署(Spring DevTools)
  • 反射 + 代理滥用
java.lang.OutOfMemoryError: Metaspace

2️⃣ 类加载器泄漏

  • Web 容器(Tomcat)反复部署
  • 自定义 ClassLoader 未释放

七、如何排查元空间问题?

1️⃣ 看 JVM 参数

jinfo <pid> | grep Metaspace

2️⃣ 看内存占用

jstat -gc <pid>

关注:

MU  → Metaspace Used
MC  → Metaspace Capacity

3️⃣ dump 分析

jmap -dump:live,format=b,file=meta.hprof <pid>

用 MAT / VisualVM 看:

  • 类数量
  • ClassLoader 数量

八、一句话总结

元空间是 JDK 8 后用来存储类元数据的本地内存区域,替代永久代,默认动态扩容,但仍可能因类加载过多而 OOM。

如果你愿意,我也可以:

  • 用 图解方式讲
  • 对比 堆 / 栈 / 元空间
  • 结合 Spring / Tomcat 实战场景讲
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手