讲师中心 微信公众号
AI工具推荐 视频效率加速

Java程序运行时的内存模型简介_理解JVM环境的基础构成

阿枫姑娘_1080

阿枫姑娘_1080

发布时间:2026-02-12 16:03:10

|

906人浏览过

|

来源于php中文网

原创

Java堆存对象和数组等线程共享数据,栈存线程私有的局部变量、参数等;对象总在堆里因栈仅存引用,实际数据需垃圾回收与线程隔离支持。

java程序运行时的内存模型简介_理解jvm环境的基础构成

Java堆和栈到底存什么,为什么对象总在堆里

Java程序运行时的内存划分不是凭空设计的,而是为了配合垃圾回收和线程隔离。堆(Heap)是所有线程共享的区域,你用 new 创建的对象、数组,全在这里分配;栈(Java Virtual Machine Stacks)则是每个线程私有的,只存局部变量、方法参数、返回地址这些生命周期明确的小东西。

常见错误现象:把大对象(比如几十MB的字节数组)反复在方法里声明,栈不会崩,但堆会快速撑满——因为栈只存引用,实际数据还在堆上。

  • 基本类型变量(int、boolean)在栈里存值;引用类型变量(如 String、ArrayList)在栈里存地址,对象本体一定在堆里
  • 逃逸分析可能让某些对象“栈上分配”,但这只是JVM优化,开发者不能直接控制,也不该依赖
  • 栈空间默认较小(一般1MB左右),递归过深或局部变量过多会触发 StackOverflowError;堆空间默认较大(如G1默认初始4MB,可动态扩展),但溢出报的是 OutOfMemoryError: Java heap space

JVM方法区去哪儿了:从永久代到元空间的变化

方法区存放类信息、常量、静态变量、即时编译后的代码。它不等同于“永久代(PermGen)”,后者只是JDK 7及之前HotSpot对方法区的一种实现;JDK 8起彻底移除了永久代,改用本地内存实现的元空间(Metaspace)。

使用场景:动态生成类(如Spring CGLIB代理、Groovy脚本热加载)容易撑爆方法区。以前调 -XX:MaxPermSize,现在得调 -XX:MaxMetaspaceSize。

立即学习“Java免费学习笔记(深入)”;

Java注释规范Skills
Java注释规范Skills

当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。

下载
  • 字符串常量池在JDK 7后从永久代移到了堆中,所以 String.intern() 的行为变了:重复字符串不再导致永久代OOM,但可能加重堆压力
  • 元空间使用本地内存,理论上只受系统限制,但没设 -XX:MaxMetaspaceSize 时仍可能因类加载器泄漏(如Web应用热部署未清理)导致本地内存耗尽
  • java.lang.OutOfMemoryError: Metaspace 出现时,优先检查是否频繁定义新类,而不是盲目加大参数

直接内存不是JVM内存,但Java程序一样会用到

直接内存(Direct Memory)不在JVM规范定义的运行时数据区里,它由操作系统管理,但Java通过 java.nio.ByteBuffer.allocateDirect() 可以申请。典型用于NIO读写、Netty零拷贝等高性能场景。

容易踩的坑:直接内存不受 -Xmx 控制,但总量受 -XX:MaxDirectMemorySize 限制(默认等于 -Xmx)。忘了设这个值,又大量用 allocateDirect,就会触发 OutOfMemoryError: Direct buffer memory。

  • 直接内存的GC不走常规堆回收流程,依赖 Cleaner 机制,在Full GC时才尝试释放——这意味着它可能比堆对象更晚被回收
  • 用 ByteBuffer.wrap(byte[]) 是堆内缓冲区,allocateDirect() 才是真正的直接内存;别以为用了NIO就自动走直接内存
  • 监控工具如JConsole、VisualVM默认不显示直接内存用量,需看 java.lang:type=MemoryPool,name=Code Cache 之外的 java.lang:type=MemoryPool,name=Metaspace 和 java.lang:type=MemoryPool,name=Compressed Class Space 并不包含它,得查 java.lang:type=MemoryPool,name=Direct Buffer Pool(如果支持)或用 jstat -gc 看 CCST 和 YGC 之外的 DC(Direct Count)字段

线程本地变量(ThreadLocal)的内存归属容易误判

ThreadLocal 变量本身是堆上的对象,但它持有的值(ThreadLocalMap 中的 Entry)是绑定在线程栈所关联的本地存储里的。关键点在于:这些值的生命周期取决于线程,而不是声明它的类或方法。

常见错误现象:Web容器中用 ThreadLocal 存用户上下文,但没在Filter或拦截器末尾调用 remove(),导致线程复用(如Tomcat线程池)时旧数据残留,甚至引发内存泄漏——因为 ThreadLocalMap 的 Entry 是弱引用Key,但Value是强引用,不手动清理就会一直挂着。

  • ThreadLocal 不是“线程私有堆”,它只是提供了一种访问线程关联数据的机制,底层仍是堆对象 + 线程对象内的引用链
  • 每次 set() 都会往当前线程的 ThreadLocalMap 里塞一个 Entry,Key是当前 ThreadLocal 实例(弱引用),Value是你传进去的对象(强引用)
  • 在可能线程复用的环境(如Servlet容器、RPC线程池)中,必须配对使用 set() 和 remove(),不能只靠 initialValue() 或 get() 自动初始化来掩盖泄漏
事情说清了就结束。真正难的不是记住哪块内存放什么,而是当 OutOfMemoryError 报出来时,你能一眼看出它属于哪个区域、对应哪种使用模式——这需要结合日志、参数、代码上下文一起判断,而不是背概念。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

相关专题

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

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

865

2023.10.26

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

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

304

2024.02.23

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

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

489

2024.02.23

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

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

305

2024.02.23

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

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

348

2024.02.23

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

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

349

2024.02.23

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

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

601

2024.02.23

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

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

322

2024.02.23

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

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

精品课程

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

共0课时 | 0人学习

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

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn