Java内存区域

运行时数据区域

JVM运行时数据区域模型

程序计数器

概念: 程序计数器是当前线程所执行的字节码的行号指示器。分支、循环、跳转、异常处理、线程恢复等都依赖程序计数器完成。

特性: 每个线程独一份,各线程之间的程序计数器互不影响,独立存储,即线程私有

注意:

  1. 如果当前线程执行的是Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;如果当前线程正在执行的是本地方法(Native),则计数器值为空(Undefined)。
  2. 程序计数器不会内存溢出。

Java虚拟机栈

虚拟机栈模型

概念: Java方法执行的线程内存模型;每个方法被执行的时候都会同步创建一个栈帧用于存放局部变量表、操作数栈、动态连接、方法出口等信息。每个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

特性:

  1. 线程私有
  2. 每个栈帧的内部结构
    1. 局部变量表存放了编译期间的基本数据类型(boolean、byte、char、short、int、long、float、double)、对象引用(指向对象的引用指针)和returnAddress类型(指向一条字节码指令的地址)
    2. 操作数栈:主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。
    3. 动态链接:指向运行时常量池的方法引用。
    4. 方法返回地址:用来存放调用该方法的 PC 寄存器的值。(退出方法后的程序位置)
    5. 附加信息

注意:
8. 线程请求的深度大于虚拟机所允许的深度,则抛出StackOverflowError异常
9. 如果虚拟机栈内存可动态扩展,当栈扩展无法申请到足够内存,则抛出OutOfMemoryError异常

本地方法栈

概念: 其他语言编写的、被Native修饰的本地方法。

概念: 存放对象和数组

特性:

  1. 线程共享
  2. 虚拟机启动时创建
  3. 为了更好的分配和回收内存,Java堆可以划分出多个线程私有的分配缓冲区(TLAB)以提升效率
  4. Java堆可以处于物理上不连续的内存空间中(逻辑上应被视为连续),大对象(如数组)为追求高效一般会要求连续的内存空间。
  5. 堆内存可固定,也可扩展(-Xmx和-Xms),无法扩展时会抛OutOfMemoryError异常。

方法区

概念: 存储虚拟机加载的类型信息、常量、静态常量、即时编译器编译后的代码缓存等数据。

特性: 线程共享。

注意:

  1. 方法区时一个概念,不同虚拟机或不同版本对其实现不同。
  2. JDK1.6及以前,方法区时通过堆内存中的永久代来实现的,初衷是为了能够像管理堆一样管理方法区。这很容易导致堆内存溢出;JDK1.7时,将字符串常量和静态常量等移植到了Java堆(不是永久代);JDK1.8以后,完全放弃了永久代的概念,通过在本地内存中实现的元空间来代替。

运行时常量池

概念: 是方法区的一部分,用于存放编译期间生成的各种字面量和符号引用(常量池表)
注意:

  1. 具备动态性,常量不要求编译期才能产生,运行期间产生的常量也能被放入池中。(String :: intern())
  2. 常量池无法再申请到内存时会抛OutOfMemoryError

直接内存

概念: JDK1.4引入了NIO类,一种基于通道(Channel)与缓冲区(Buffer)的I/O方式,他可以使用Native函数库直接分配堆外内存,然后通过堆中的DirectByteBuffer对象作为这块内存的引用进行操作。

注意: 直接内存不是虚拟机运行时区域的一部分,但也可能导致OutOfMemoryError异常。受本机总内存大小限制,当每个内存区域总和大于物理内存时,直接内存动态扩展会导致OutOfMemoryError。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值