Java内存区域模型

JAVA内存区域模型

  • JVM虚拟机在执行java字节码文件时会把他所管理的内存划分为几个不同的区域。(在JDK1.8和1.8之前有些改变)

JDK1.8之前:
在这里插入图片描述

JDK1.8及之后:
在这里插入图片描述
其中线程共享的区域有:

  • 堆内存
  • 方法区
  • 直接内存

线程私有的区域有:

  • 虚拟机栈(java方法栈)
  • 本地方法栈(native修饰的方法栈)
  • 程序计数器

虚拟机栈

虚拟机栈是线程私有的,每个线程都有它自己的虚拟机栈。它的生命周期和线程相同。
虚拟机栈就像数据结构中的栈,栈里保存的元素是一个个的栈帧,每执行一个java方法就会有一个栈帧被压入虚拟机栈,每完成一个java方法,其所对应的栈帧会从虚拟机栈中弹出。

栈帧

每个Java方法在被执行时,Java虚拟机会同步的为这个方法创建一个栈帧,用来存放方法里用到的局部变量。
栈帧由局部变量表、操作数栈、动态连接、方法出口等信息组成。
在这里插入图片描述

局部变量表

局部变量表用来存放编译器可知的基本数据类型对象引用类型(reference类型,不是对象本身),还有returnAddress类型(程序计数器的值,后面会介绍)。
需要注意的是,当执行一个方法时,这个方法的局部变量表的大小是完全确定的,在方法运行的期间不会改变。(PS:这里指的大小是指变量槽的数量,只有double和long类型使用两个变量槽,其他类型变量使用1个变量槽。 至于每个变量槽使用多大空间(32bit,64bit,或者更多),由具体实现虚拟机的厂商自行决定)。

异常

在JAVA虚拟机规范中,对虚拟机栈这个内存区域定义了两种异常

  • SrackOverflowError
  • OutOfMemoryError

如果线程请求的栈深度大于虚拟机栈的容量,会抛出StackOverflowError
在一些虚拟机中请求的栈大于虚拟机栈容量时,虚拟机栈可以动态扩展。当虚拟机栈扩展时不能申请到足够的内存空间会抛出OutOfMemoryError

本地方法栈

本地方法栈和虚拟机栈非常相似,唯一不同的是虚拟机栈里面的方法是java方法,而本地方法栈里的方法是本地方法。
在某些虚拟机中(如HotSpot)直接把本地方法栈和虚拟机栈合二为一。

本地方法

本地方法是用native修饰的方法,使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用,在jdk中你看不到这些方法的实现。

程序计数器

程序计数器又名PC寄存器(ProgramCounter)

  1. 每个线程启动的时候,都会创建一个PC(Program Counter,程序计数器)寄存器。PC寄存器里保存有当前正在执行的JVM指令的地址。 每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。保存下一条将要执行的指令地址的寄存器是 :PC寄存器。PC寄存器的内容总是指向下一条将被执行指令的地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。

  2. 每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。

  3. 这块内存区域很小,它是当前线程所执行的字节码的行号指示器,字节码解释器通过改变这个计数器的值来选取下一条需要执行的字节码指令。

  4. 如果执行的是一个native方法,那这个计数器指向undefined。

堆内存

我们new出来的对象都会在这里分配内存,这里也是垃圾回收的主要区域。
现代的垃圾回收器采用分代回收,可以将堆内存分成两块:

  • 新生代(存放存活时间较短的对象)
  • 老年代(存活时间较长的对象,或者占用内存较大的对象)

堆内存不需要连续的内存空间,并且可以动态扩容,当扩容失败后抛出OOM异常

方法区

  1. 方法区是JDK1.8之前存在的区域,在JDK1.8中方法区被移除,取而代之的是直接使用内存的元空间。
  2. 方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
  3. 这个区域和堆内存一样不需要连续的内存空间,可以动态扩容,扩容失败后会抛出OOM异常。
  4. 我们一般不在方法区执行垃圾回收,所以有些虚拟机使用永久代来实现方法区。

运行时常量池

运行时常量池是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有常量池表(用于存放编译期生成的各种字面量和符号引用)

既然运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时会抛出 OutOfMemoryError 错误。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值