JVM自动内存管理——java内存区域与内存溢出异常

1概述

对于java来说,在虚拟机自动内存管理机制的帮助下,不需要为每个操作写配对的delete/free代码,不过,一但出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎么使用内存,那么排查问题将会十分困难。

2运行时数据区域

2.1程序计数器

程序计数器是一块比较小的内存区域,可以看成当前线程执行字节码的行号指示器。

由于jvm的多线程是通过线程轮换,分配处理器的执行时间来实现的,为了线程切换后能回到正确的执行位置,每条线程都需要应该独立的程序计数器,个线程程序计数器间不受影响。

如果线程正在执行一个Java方法,那么计数器记录的是虚拟机字节码的地址,如果执行的是本地方法,则为空。

此内存区域是唯一一个没有规定任何OutOfMemoryError情况的区域

2.2 java虚拟机栈

java虚拟机栈也是线程私有的,它的生命周期和线程相同。虚拟机栈描述的是java执行的线程内存模型:每个方法被执行时,jvm会同步创建一个栈帧用于存储局部变量表,操作数栈等信息,方法从调用到执行完毕的过程,对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

这个区域定义了两种异常状况:

如果线程请求的栈深度大于虚拟机允许的深度,抛出StackOverflowError异常;

如果虚拟机栈容量可以动态扩展,当扩展无法申请足够内存时会抛出OutOfMemoryError异常。

2.3 本地方法栈

与虚拟机栈相似,只是一个是java方法,一个是本地方法。

2.4 java堆

对于java应用程序来说,java堆是虚拟机管理的内存中最大的一块。被所有线程共享。在虚拟机启动时创建,唯一目的是存放对象实例。

java堆是垃圾收集器管理的区域,java堆主流的是可扩展的,从分配内存角度,java堆可以分出多个线程私有的分配缓冲区,细分只是为了更好地回收内存,如果堆没有内存可以分配且无法扩展,jvm抛出OutOfMemoryError异常。

2.5方法区

是线程共享的内存区域,方法区可以不选择垃圾收集,所以方法区的内存回收很难令人满意。方法区无法满足内存需求时,也会抛出OutOfMemoryError异常。

2.6运行时常量池

是方法区的一部分,用来放编译后的字面量和符号引用。

2.7 直接内存

直接内存不是运行时数据区的一部分,jdk1.4中加的NIO,可以使用native函数库直接分配堆外内存,然后通过存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。

虽然不受java堆大小限制,但仍然会受本机总内存限制。

相关推荐
峥嵘life2 分钟前
Andorid 打开热点,关闭有线网,ifconfig卡死分析解决
java·服务器·网络
NiceCloud喜云6 分钟前
ClaudeAPI 接入 n8n / Dify / Open WebUI 实战:Base URL 配置、调用示例与排错
开发语言·ai·chatgpt·aigc
HillVue9 分钟前
Token 叙事退潮,DAA 重新定义 AI 价值标准
java·人工智能·eclipse
行者全栈架构师13 分钟前
【码动四季】Spring Boot 可观测性体系:Micrometer + OpenTelemetry + Grafana 全链路搭建
java·算法·架构
庵中十三居士13 分钟前
【纯AI无人工修改】AI Agent从0到1实战:50行Python手写核心循环,一次看懂所有Agent框架的底层逻辑
开发语言·人工智能·python
甄同学24 分钟前
第二十篇:MCP协议集成,Claude Code如何扩展AI Agent的能力边界
开发语言·人工智能·qt
TDengine (老段)31 分钟前
TDengine JOIN 完整语法 — Inner/Outer/ASOF/Window 全语法详解
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
@atweiwei1 小时前
Langchainrust:中LLM-as-a-Judge,用 Rust 实现一套 LLM 评估系统
开发语言·后端·ai·rust·llm·rag
风华圆舞1 小时前
鸿蒙HarmonyOS 多模态输入实战 —— 图片与文档输入智谱/DeepSeek
开发语言·人工智能·华为·php·harmonyos·arkts·arkui
@灯神1 小时前
SpringAI系列|第1篇:SpringAI概述与快速上手
java·人工智能·spring·ai·ai编程