Java里JVM内存区域如何划分_Java内存结构核心概念说明

发布时间 - 2026-01-01 00:00:00    点击率:
JVM内存区域由启动时划分,非Java代码控制;方法区Java8+用Metaspace替代PermGen,类元数据存Metaspace而字符串常量池在堆中;堆分新生代(Eden+S0+S1)和老年代,默认1:2;栈、本地方法栈、程序计数器为线程私有;直接内存属本机内存,不归JVM运行时数据区管。

Java 的 JVM 内存区域不是由 Java 代码直接控制的,而是由 JVM 启动时按规范划分的运行时数据区;搞不清这些区域,排查 OutOfMemoryErrorStackOverflowError 就容易定位错方向。

方法区(Metaspace)和永久代(PermGen)的区别在哪

Java 8 及以后彻底移除了 PermGen,改用本地内存实现的 Metaspace。这意味着:

  • Metaspace 默认无上限(受本机内存限制),而 PermGen 是堆内固定大小区域,容易因加载大量类(如热部署、反射、Groovy/Scala 动态生成类)触发 java.lang.OutOfMemoryError: PermGen space
  • 配置方式变了:-XX:MaxPermSize 在 Java 8+ 已无效;改用 -XX:MaxMetaspaceSize-XX:MetaspaceSize
  • 类元数据(如 Class 对象、常量池、字段/方法信息)存在这里,但字符串常量池(StringTable)在 Java 7+ 已移到堆中

堆内存(Heap)里新生代和老年代怎么分,为什么这么分

堆是 GC 主战场,逻辑上划分为新生代(Young Gen)和老年代(Old Gen),默认比例通常是 1:2(即新生代占 1/3),但可通过 -XX:NewRatio 调整。

  • 新生代再细分为 Eden 区和两个 Survivor 区(S0S1),对象优先分配在 Eden;一次 Minor GC 后存活对象进入 Survivor,经历多次 GC 仍存活(由 -XX:MaxTenuringThreshold 控制,默认 15)才晋升到老年代
  • 大对象(如大数组)可能直接进老年代(取决于 -XX:PretenureSizeThreshold 设置,且仅对 Serial/Parallel 收集器有效)
  • 老年代空间不足触发 Full GC,代价远高于 Minor GC;所以频繁 Full GC 往往说明对象过早晋升,或老年代本身太小

栈、本地方法栈、程序计数器为什么是线程私有的

这三个区域生命周期与线程绑定,每个线程启动时 JVM 自动为其分配独立空间:

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

  • Java 虚拟机栈 存储局部变量、操作数栈、动态链接、方法出口等,每个方法调用对应一个栈帧;StackOverflowError 多因递归过深或局部变量表过大
  • 本地方法栈 为 native 方法服务(如 java.io.FileInputStream#read0() 底层调用 C 函数),错误表现和 Java 栈类似
  • 程序计数器 记录当前线程执行字节码的行号,唯一不会 OOM 的区域;多线程环境下靠它保证线程切换后能恢复执行位置

直接内存(Direct Memory)算不算 JVM 内存

不算 JVM 运行时数据区的一部分,但它被 java.nio.ByteBuffer.allocateDirect() 分配,使用的是本机内存,不受 -Xmx 控制——这点极易被忽略。

  • 常见于 NIO 框架(如 Netty)、高性能文件读写场景;泄漏表现为物理内存持续上涨,但 jstat 显示堆内存正常
  • 可通过 -XX:MaxDirectMemorySize 限制,默认值等于 -Xmx(注意:不是自动等于,是 JVM 实现的默认行为)
  • 释放依赖 Cleaner(Java 9+)或 Finalizer(旧版),不及时 GC 可能导致 OutOfMemoryError: Direct buffer memory

真正难的不是记住各区域名字,而是看到 OutOfMemoryError 日志时,能结合 GC 日志、堆转储(heap dump)和系统监控,快速判断是 Metaspace 不够、老年代碎片化、还是 DirectByteBuffer 泄漏——这些区域之间没有绝对隔离,但错误现象和排查路径差异极大。


# java  # js  # 字节  # 虚拟机  #   # stream  # 区别  # overflow  # 字符串常量  # 为什么 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  Laravel Admin后台管理框架推荐_Laravel快速开发后台工具  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  中山网站推广排名,中山信息港登录入口?  5种Android数据存储方式汇总  Python并发异常传播_错误处理解析【教程】  高端企业智能建站程序:SEO优化与响应式模板定制开发  javascript日期怎么处理_如何格式化输出  Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】  如何用低价快速搭建高质量网站?  企业网站制作这些问题要关注  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  开心动漫网站制作软件下载,十分开心动画为何停播?  Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】  php打包exe后无法访问网络共享_共享权限设置方法【教程】  iOS正则表达式验证手机号、邮箱、身份证号等  JavaScript如何实现错误处理_try...catch如何捕获异常?  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  香港服务器WordPress建站指南:SEO优化与高效部署策略  Laravel怎么上传文件_Laravel图片上传及存储配置  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  青岛网站建设如何选择本地服务器?  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  如何快速查询域名建站关键信息?  如何在橙子建站中快速调整背景颜色?  Android利用动画实现背景逐渐变暗  iOS验证手机号的正则表达式  浅析上传头像示例及其注意事项  Java遍历集合的三种方式  再谈Python中的字符串与字符编码(推荐)  香港服务器如何优化才能显著提升网站加载速度?  Laravel DB事务怎么使用_Laravel数据库事务回滚操作  EditPlus中的正则表达式 实战(1)  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  Linux网络带宽限制_tc配置实践解析【教程】  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  Laravel如何创建自定义Artisan命令?(代码示例)  简历没回改:利用AI润色让你的文字更专业  jQuery 常见小例汇总  Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】  如何确保西部建站助手FTP传输的安全性?  黑客如何通过漏洞一步步攻陷网站服务器?  如何在Windows 2008云服务器安全搭建网站?  Laravel如何使用Blade组件和插槽?(Component代码示例)