Skip to content

面试速答(先看这里)

**一句话结论:**Metaspace(元空间)是Java 8 引入的,用来替代了 PermGen(永久代)的,他主要用来存储: 类的元信息 (类的结构、方法签名、注解、常量池等),他和 PermGen 最大的区别是: Metaspace 是存在堆外内存的,而永久代是在堆上的。

60秒标准回答:

Metaspace(元空间)是Java 8 引入的,用来替代了 PermGen(永久代)的,他主要用来存储: 类的元信息 (类的结构、方法签名、注解、常量池等),他和 PermGen 最大的区别是: Metaspace 是存在堆外内存的,而永久代是在堆上的

虽然元空间不在堆上,但是如果元空间满了,是会发生FullGC的(虽然大多数情况下都没用)

如果元空间满了,或者发生了溢出,或者是频繁的FullGC,那么可以考虑以下几种情况

**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点

回答主线:

  • **要点1:**虽然元空间不在堆上,但是如果元空间满了,是会发生FullGC的(虽然大多数情况下都没用)。
  • **要点2:**如果元空间满了,或者发生了溢出,或者是频繁的FullGC,那么可以考虑以下几种情况:
  • **要点3:**类加载并不只是说你项目中的你写的Class太多了,这些往往都不是类加载太多的主要原因,而是需要考虑哪些频繁动态生成类,比如:动态代理、CGLIB、JSP编译、Groovy脚本等等,他们都会在运行期动态生成类。
  • **要点4:**比如下面这个问题,就是一个元空间溢出的问题,具体原因就是类加载的太多了:
  • **要点5:**类加载泄露,估计很多人不知道啥意思,其实就是同一个类名,被多个类加载器加载,因为会被认为是不同类,所以每个类加载器持有它加载的类, 只要类加载器没有被 GC,类元信息就不能释放。

**记忆锚点:**Metaspace → PermGen → FullGC → MaxMetaspaceSize → 在运行期动态生成类 → 为会被认为是不同类

易错提醒:

  • 比如下面这个问题,就是一个元空间溢出的问题,具体原因就是类加载的太多了: 2、类加载器泄漏 类加载泄露,估计很多人不知道啥意思,其实就是同一个类名,被多个类加载器加载,因为会被认为是不同类,所以每个类加载器持有它加载的类, 只要类加载器没有被 GC,类元信息就不能释放。
  • 一般来说元空间用的都是堆外内存,默认都是可以自动扩容的,容量也都很大,但是如果有的时候你用MaxMetaspaceSize指定了大小,那么也会容易被干满。

加分表达:

  • 虽然元空间不在堆上,但是如果元空间满了,是会发生FullGC的(虽然大多数情况下都没用)。
  • 如果元空间满了,或者发生了溢出,或者是频繁的FullGC,那么可以考虑以下几种情况: 1、 类加载的太多了(最常见!

追问准备:

  • 围绕「Metaspace」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「PermGen」:底层原理是什么?使用时有哪些边界和常见坑?
  • 围绕「FullGC」:底层原理是什么?使用时有哪些边界和常见坑?
  • 如果线上出现异常,你会如何定位、验证并规避?

典型回答 ​

Metaspace(元空间)是Java 8 引入的,用来替代了 PermGen(永久代)的,他主要用来存储:类的元信息(类的结构、方法签名、注解、常量池等),他和 PermGen 最大的区别是:Metaspace 是存在堆外内存的,而永久代是在堆上的。

虽然元空间不在堆上,但是如果元空间满了,是会发生FullGC的(虽然大多数情况下都没用)。

如果元空间满了,或者发生了溢出,或者是频繁的FullGC,那么可以考虑以下几种情况:

1、类加载的太多了(最常见!)

类加载并不只是说你项目中的你写的Class太多了,这些往往都不是类加载太多的主要原因,而是需要考虑哪些频繁动态生成类,比如:动态代理、CGLIB、JSP编译、Groovy脚本等等,他们都会在运行期动态生成类。

比如下面这个问题,就是一个元空间溢出的问题,具体原因就是类加载的太多了:

📄 ✅频繁FullGC问题排查

打开文档:✅频繁FullGC问题排查

2、类加载器泄漏

类加载泄露,估计很多人不知道啥意思,其实就是同一个类名,被多个类加载器加载,因为会被认为是不同类,所以每个类加载器持有它加载的类,只要类加载器没有被 GC,类元信息就不能释放。就会持续占用你空间、。

比较常见的就是在热部署的情况下,比如Tomcat/IDEA热重启时类加载器没释放。

3、元空间太小

一般来说元空间用的都是堆外内存,默认都是可以自动扩容的,容量也都很大,但是如果有的时候你用MaxMetaspaceSize指定了大小,那么也会容易被干满。