深入理解Java中的运行时数据区划分_JDK 8后方法区的物理迁移

夏杰姑娘_9078

夏杰姑娘_9078

2026-02-26

548人浏览

原创

Java 8 彻底移除永久代是因它与GC协同差、易触发OutOfMemoryError,改用基于本地内存的元空间替代,由-XX:MaxMetaspaceSize控制,默认无上限,需防泄漏。

深入理解java中的运行时数据区划分_jdk 8后方法区的物理迁移

Java 8 为什么彻底移除了永久代(PermGen)

因为永久代设计上无法与垃圾回收机制协同,容易触发 java.lang.OutOfMemoryError: PermGen space,尤其在热部署、大量反射或动态类生成场景下。JDK 8 不是“改名”,而是用元空间(Metaspace)替代——它从 JVM 堆外内存(本地内存)分配,不再受 -XX:MaxPermSize 限制,改由 -XX:MaxMetaspaceSize 控制。

关键区别在于:永久代是堆的一部分,受 GC 管理;元空间则使用本地内存,仅对类元数据做轻量级回收(如类卸载),且默认无上限(可能耗尽系统内存)。

  • 旧参数 -XX:PermSize 和 -XX:MaxPermSize 在 JDK 8+ 已被忽略,设了也不生效
  • 若应用升级后仍报 OutOfMemoryError,大概率是忘了配 -XX:MaxMetaspaceSize,导致元空间无限扩张
  • Spring Boot 2.x + Tomcat 8+ 热重启频繁时,未卸载的 ClassLoader 会持续占用元空间,必须配合 -XX:+TraceClassUnloading 排查

Metaspace 内存到底存在哪儿

元空间物理上位于本地内存(native memory),不是堆,也不是直接映射到操作系统的虚拟内存区;它是通过 mmap 分配的多个不连续内存块,由 JVM 自己管理。这意味着:

  • jstat -gc 输出中不再有 PC(Permanent Capacity)字段,取而代之是 MC(Metaspace Capacity)、MU(Metaspace Used)
  • jmap -histo:live 不统计类元数据大小,要查元空间用量得用 jstat -gccapacity 或 JMX 的 java.lang:type=MemoryPool,name=Metaspace
  • Linux 下可通过 pmap -x 观察大块 anon 匿名内存,其中就包含元空间分配区

哪些操作真正触发 Metaspace 分配

不是每个 new 类实例都会动元空间,只有加载、链接、初始化类结构时才写入元空间。典型触发点包括:

Java Api Extractor
Java Api Extractor

从 Java 项目中提取 Controller 层接口定义为 JSON 数据。

下载
  • 首次调用 Class.forName("xxx") 或通过类加载器 loadClass()
  • 使用 Unsafe.defineAnonymousClass()(如 Lambda、动态代理生成类)
  • 反射调用 Method.setAccessible(true) 后,JVM 可能缓存解析后的字节码结构
  • 使用 CGLIB 或 ByteBuddy 运行时生成类(如 Spring AOP、Mockito)

注意:String.intern() 在 JDK 7+ 已移到堆中,和元空间无关;但 Class> clazz = obj.getClass() 不分配新元数据,只是引用已有项。

排查 Metaspace 泄漏的实用路径

泄漏本质是 ClassLoader 持有已加载类的引用,导致类无法卸载,元空间持续增长。常见于 Web 容器反复部署、OSGi、或自定义类加载器未正确释放。

  • 启用 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps,观察日志中是否出现 Full GC (Metadata GC Threshold) —— 这说明元空间快满了,触发了 Full GC 来尝试回收
  • 用 jcmd VM.native_memory summary scale=MB 查看 Internal 区域是否异常偏高(元空间归在此类)
  • dump 后用 jhat 或 MAT 打开 heap.hprof,按 java.lang.ClassLoader 分组,找数量突增的子类加载器实例
  • 确认类加载器是否持有 ThreadLocal、静态集合、或未关闭的资源(如 JDBC Driver 注册未反注册)

最常被忽略的一点:即使代码里显式调用了 ClassLoader.close(),若该加载器加载的类仍有活跃引用(比如某个单例对象持有了它的 Class 实例),JVM 仍不会卸载这些类,元空间也不会释放。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
如何配置Tomcat环境变量
如何配置Tomcat环境变量

配置Tomcat环境变量需要在系统中添加CATALINA_HOME变量,并将Tomcat的安装路径添加到PATH变量中。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.26

885

5

idea如何集成Tomcat
idea如何集成Tomcat

idea集成Tomcat的步骤:1、添加Tomcat服务器配置;2、配置项目部署;3、运行Tomcat服务器;4、访问项目;5、注意事项;6、关闭Tomcat服务器。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

324

5

怎么查看Tomcat源代码
怎么查看Tomcat源代码

查看Tomcat源代码的步骤:1、下载Tomcat源代码;2、在IDEA中导入Tomcat源代码;3、查看源代码;4、理解Tomcat的工作原理;5、参与社区和贡献;6、注意事项;7、持续学习和更新;8、使用工具和插件。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

489

5

常见的tomcat漏洞有哪些
常见的tomcat漏洞有哪些

常见的tomcat漏洞有:1、跨站脚本攻击;2、跨站请求伪造;3、目录遍历漏洞;4、缓冲区溢出漏洞;5、配置漏洞;6、第三方组件漏洞。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

305

5

tomcat日志乱码怎么解决
tomcat日志乱码怎么解决

tomcat日志乱码的解决办法:1、修改tomcat的日志编码设置;2、检查ide的编码设置;3、检查操作系统的编码设置;4、使用过滤器处理日志;5、检查外部系统的编码设置;6、检查文件编码方式等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

348

5

weblogic和tomcat有哪些区别
weblogic和tomcat有哪些区别

weblogic和tomcat的区别:1、功能;2、性能;3、规模;4、价格;5、安全性;6、配置和管理;7、社区支持;8、集成能力;9、升级和更新;10、可靠性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

349

5

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

601

5

tomcat启动闪退怎么解决
tomcat启动闪退怎么解决

tomcat启动闪退的解决办法:1、检查java环境;2、检查环境变量配置;3、检查端口被占用;4、检查配置文件编码;5、检查启动时需要的配置文件;6、检查相关文件是否丢失;7、检查防火墙和杀毒软件设置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

322

5

有哪些常见的tomcat漏洞
有哪些常见的tomcat漏洞

常见的tomcat漏洞有:1、跨站脚本攻击;2、跨站请求伪造;3、目录遍历漏洞;4、缓冲区溢出漏洞;5、配置漏洞;6、第三方组件漏洞。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

3013

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习