JVM 系列(1)内存区域

Java内存区域

在这里插入图片描述

1.1 程序计数器(线程私有)

概念 : 一块较小的内存区域,可看作为当前行号的指示器
作用 :(1) 通过改变计数器的值选取吓一跳需要执行的字节码指令
		 (2) 作为控制流的的指示器,分支,循环,跳转,异常处理,线程恢复等等需要依靠计数器完成
异常:是《java虚拟机规范》中没有任何规定OOM的区域

2.1 虚拟机栈(线程私有)、

概念 : 生命周期与线程相同,虚拟机栈描述的是java方法的内存模型
			每个方法创建的时候都会同步创建一个栈帧
			栈帧用于存储局部变量表,操作数栈,动态链接,方法出口 等信息
			每一个方法被掉哦那个直至执行完毕的过程,对应一个栈帧,入栈到出栈的过程
异常 :  (1)线程请求的栈深度 > 虚拟机栈允许深度  --->>>StackOverflowError
		   (2)如果虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的空间---->>>OOM
	*注意:HotSpot是不支持动态扩展的,所以HotSpot上不会因为虚拟机栈无法扩展而导致OOM(只要线程申请栈空间成功就不会有OOM)
			    但是如果申请时就失败了,会出现OOM	   	*

3.1 本地方法栈(线程私有)

概念 :与虚拟机栈发挥的作用相似,本地方法栈是为虚拟机使用到的本地方法服务

4.1 堆(线程共享)

概念 :所有的对象实例以及数组都应该在堆上分配
异常 :java堆中没有内存完成分配,且堆 也无法再扩展,java虚拟机抛出OOM

5.1 方法区(共享)

概念:存储已经被虚拟机加载的类信息,常量就,静态变量,即时编译器编译后的代码缓存等数据
异常:  如果方法区无法满足新的内存分配需求,将抛出OOM
扩展:
永久代:
	永久代并不等价于方法区
	如何实现永久代不受《java虚拟机规范》的约束,并不要求统一
	jdk6及其以前----使用永久代实现方法区
	jdk7---将原本在永久代的字符串常量池,静态变量移除
	jdk8---放弃永久代,在本地内存中实现的原空间代替

5.1.1运行时常量池

概念 :用于存放编译器生成的各种字面量和符号引用
特点 : 动态性
		 常量并不一定只有编译器才能生成,运行期间也可以将新的常量放入常量池
		 例如String的intern()
异常 : 因为时方法区的一部分,收到方法区的内存限制,常量池无法申请到足够内存时---OOM

6.1 直接内存(不是虚拟机运行时的一部分)

概念:java直接操作的本地内存
用途:jdk1.4引入NIO ,可以使用Native函数库直接分配对外内存
		  这样能在一些场景显著提高性能,因为避免了java堆和Native堆来回复制内存
异常:收到本机内存和寻址空间的限制 ,一般会根据实际内存去设置-Xmx等信息,但经常忽略直接内存
		  使得各个内存区域总和大于物理内存限制,从而导致动态扩展时 OOM

猜你喜欢

转载自blog.csdn.net/kznsbs/article/details/107524533