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堆大小限制,但仍然会受本机总内存限制。

相关推荐
腻害兔2 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
SeaTunnel2 小时前
从 Python Script 地狱到标准化数据集成框架
大数据·开发语言·python·程序员·代码·seatunnel
碎光拾影2 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
Marst Code3 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
Miao121313 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言
腻害兔3 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程
CRMEB系统商城4 小时前
开源自建还是SaaS订阅?算一笔3年经济账
java·大数据·开发语言·开源
keyipatience5 小时前
线程栈与TLS和线程互斥
java·linux·服务器·开发语言·ubuntu
我的xiaodoujiao5 小时前
快速学习Python基础知识详细图文教程9--函数进阶
开发语言·python·学习·测试工具
weixin_408099676 小时前
2026 图片去水印 API 接口完全指南:一键去除图片水印(附 Python/Java/PHP/C# 示例)
java·python·php·图片处理·api调用·图片去水印·石榴智能