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

相关推荐
西部风情8 分钟前
聊聊并发、在线、TPS
android·java·数据库
爬虫程序猿1 小时前
用 Python 给京东商品详情做“全身 CT”——可量产、可扩展的爬虫实战
开发语言·爬虫·python
顾漂亮2 小时前
Token快过期的三种续期方案
java·spring·状态模式
徐同保3 小时前
tailwindcss暗色主题切换
开发语言·前端·javascript
蓝纹绿茶3 小时前
bash:**:pip:***python: 错误的解释器: 没有那个文件或目录
开发语言·python·pip
云知谷3 小时前
【经典书籍】C++ Primer 第15章类虚函数与多态 “友元、异常和其他高级特性” 精华讲解
c语言·开发语言·c++·软件工程·团队开发
START_GAME4 小时前
深度学习Diffusers:用 DiffusionPipeline 实现图像生成
开发语言·python·深度学习
牢七4 小时前
mwf攻防。
java
不爱编程的小九九4 小时前
小九源码-springboot088-宾馆客房管理系统
java·开发语言·spring boot
Evand J5 小时前
【MATLAB例程】到达角度定位(AOA),平面环境多锚点定位(自适应基站数量),动态轨迹使用EKF滤波优化。附代码下载链接
开发语言·matlab·平面·滤波·aoa·到达角度