JVM-内存区域划分

本文详细介绍了JVM的运行时数据区域,包括程序计数器、虚拟机栈、堆、方法区和本地方法栈。重点讲解了虚拟机栈中的局部变量表、堆内存的分代收集以及方法区的运行时常量池。对于Java开发者来说,了解这些内存区域的工作原理有助于理解和解决内存溢出、栈溢出等问题。


1.运行时数据区域:

  • 程序计数器
  • 虚拟机栈
  • 堆(heap)
  • 方法区
  • 本地方法栈

(1)程序计数器:

​ 当前线程所执行的字节码的行号指示器,字节码解释器在工作时通过改变该计数器的值来选取下一条要执行的字节码指令

​ 所占内存区域很小

(2)虚拟机栈(≈栈内存):

​ 线程私有,生命周期与线程相同

​ Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息

​ 每个方法从被调用到执行完成,都对应一个栈帧在虚拟机栈中从入栈到出栈的过程

​ *局部变量表:存放编译期可知的各种基本数据类型、对象引用类型和returnAddress类型(指向了一条字节码指令的地址);局部变量表所需的内存在编译期间完成分配,方法运行期间不改变大小

​ 可能出现的异常:StackOverflowError:线程请求栈深大于虚拟机允许的栈深

​ OutOfMemoryError:无法申请到足够的内存

(3)堆(堆内存heap):

​ 所有线程共享,虚拟机启动时创建,存放对象实例,几乎所有的对象实例都在这里分配内存

​ 垃圾收集器管理的主要区域,也称为 GC堆

​ 现在垃圾收集器大都采用分代收集算法,所以堆可以分为:新生代和老生代

​ 线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(TLAB)

​ Java堆内存可以处于物理上不连续的内存空间上,但是逻辑上需要是连续的

​ 可扩展的堆通过 -Xmx和-Xms 来控制大小,无法扩展时,会抛出OutOfMemoryError异常

(4)方法区:

​ 线程共享的内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

​ 该区域一般不进行垃圾回收,但并不是说这个区域内的数据永久存在(永久代perm gen)。该区域的内存回收目标主要是针对常量池的回收和对类型的卸载

​ 无法满足内存分配需求时,会出现OutOfMemoryError异常

(5)本地方法栈:

​ 为虚拟机使用到的Native方法服务

​ 此区域会抛出OutOfMemoryError异常和StackOverflowError异常

2.运行时常量池:

​ 方法区的一部分。Class文件中的常量池(存放编译期生成的各种字面量和符号引用)中的内容在类加载后会存放在方法区的运行时常量池中

​ 当常量池无法再申请到内存时会抛出OutOfMemoryError异常

3.直接内存:

​ NIO使用Native函数库直接分配的堆外内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值