JVM之java内存区域异常的相关说明

java-经验王 Java经验 发布时间:2021-10-31 22:35:00 阅读数:10419 1
下文是笔者收集的Java内存区域异常的相关简介说明,如下所示:
Java语言是运行在JVM虚拟机上的语言,它由JVM管理内存,下文笔者讲述由JVM产生的异常简介说明

JVM中内存区域分布

JVM运行java程序时
将内存分为多个不同的数据区域进行管理
这些内存区域具有不同的作用、不同创建和销毁时间
有的区域是在JVM进程启动时分配
有的区域则与用户线程(程序本身的线程)的生命周期相关
这些都是由JVM规范所规定,JVM分为以下几个运行时数据区域: 
虚拟机栈
虚拟机栈内存区域是线程私有的,
随线程启动而创建、线程销毁而销毁
虚拟机栈描述的java方法执行的内存模型
每个方法在执行开始会创建一个栈帧(Stack Frame),
用于存储局部变量表、操作数栈,动态链接、方法出口等
每个方法的调用执行和返回结束,都对应有一个栈帧在虚拟机栈入栈和出栈的过程
 局部变量表:
     用于存储局部变量,存储8种基本数据类型,引用类型的地址
	 局部变量的内存空间,在编译器可完成分配,在方法运行期间无需修改局部变量表大小
-----------------------------------------------------------------------------------------
此处可能会发生2种异常:
1.当线程请求的栈深度大于虚拟机所允许的深度(?),将抛出StackOverflowError异常
2.当虚拟机可以动态扩展,当扩展是无法申请到足够内存,将抛出OutOfMemory异常

本地方法栈

本地方法栈内存区域是是线程私有
虚拟机栈作用几乎是一样的
虚拟机栈是为java方法执行提供出入栈服务,而本地方法栈则是为虚拟机执行Native方法提供服务
 在虚拟机规范中,对本地方法栈实现方式没有强制规定,
 可以由具体虚拟机自由实现;
   HotSpot虚拟机是直接把虚拟机栈和本地方法栈合二为一实现;
---------------------------------------------------------------------------    
与虚拟机栈一样,本地方法栈同样会抛出StackOverflowError和OutOfMemory异常。

程序计算器

程序器计算器是线程私有的内存区域
可认为是线程执行字节码的行号指示器(指向一条指令),
java执行时通过改变计数器的值来获的下一条需要执行的指令,分支、循环、跳转、异常处理、线程恢复等执行顺序都要依赖这个计数器来完成
虚拟机的多线程是通过轮流切换并分配处理器执行时间实现,
处理器(对多核处理器来说是一个内核)在一个时刻只能在执行一条命令
因此线程执行切换后需要恢复到正确的执行位置,每个线程都有一个独立的程序计算器
当执行一个java方法时,这个程序计算器记录(指向)当前线程正在执行的字节码指令地址,
如果正在执行的是Native方法,这个计算器的值为undefined,
这是因为HotSpot虚拟机线程模型是原生线程模型,即每个java线程直接映射OS(操作系统)的线程,执行Native方法时,由OS直接执行,虚拟机的这个计数器的值是无用的;
由于这个计算器是一块占用空间很小的内存区域,为线程私有,不需要扩展,
是虚拟机规范中唯一一个没有规定任何OutOfMemoryError异常的区域。

堆内存(Heap)

java堆是线程共享的内存区域,是虚拟机管理的内存最大的一块区域
在虚拟机启动时创建
java堆内存:
  主要是存储对象实例,几乎所有的对象实例(包括数组)都是存储在这里
  这也是垃圾回收(GC)最主要的内存区域
---------------------------------------------------------------------
根据JVM虚拟机规范,java堆内存可以处于不连续的物理内存中
 但是要在逻辑上是连续的,并且空间扩展也没有限制,
 既可以是固定大小,也可以是棵扩展的
当堆内存没有足够的空间完成实例分配,而且也无法扩展时,将会抛出OutOfMemoryError异常

方法区

方法区和堆内存一样,是线程共享的内存区域;
存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译期编译后的代码等数据;
虚拟机规范对于方法区的实现没有过多限制,和堆内存一样不需要连续的物理内存空间,
大小可以固定或者可扩展,还可以选择不实现垃圾回收;
当方法区无法满足内存分配需求时将会抛出OutOfMemoryError异常

直接内存

直接内存不是JVM虚拟机管理内存的一部分
但这部分内存可能被频繁用到
在java程序使用到Native方法时(如 NIO),
可能会直接在堆外分配内存
但是内存总空间大小是有限的,
也会遇到内存不足的情况,一样会抛出OutOfMemoryError异常
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202110/16356909661632.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者