Java虚拟机-运行时数据区

1、概述

运行时数据区(Runtime Data Area):JVM 运行的时候操作所分配的内存区,按照线程范围可以分为“线程公共范围”和“线程私有范围”两部分内存。
在这里插入图片描述

2、线程公共范围

线程公共范围划分为“堆内存”和“非堆内存”。“堆内存”存储的是对象,垃圾收集器根据GC算法回收这些对象,“堆内存”区域可以分为“年轻代”和“年老代”(默认比例,年轻代年老代=1:2),其中,“年轻代”区域又可以分为 Eden、S0、S1三个区域(默认比例,Eden:S0:S1=8:1:1);“非堆内存”存储的是长期存活的对象,比如类的元数据、方法、常量、属性等。“非堆内存”所属区域叫做“方法区”,注意“方法区”只是一个规范不是具体实现,其具体实现的内存区域是“永久代”(JDK1.7 及以前版本,“永久代”内存和“堆内存”是物理内存相互隔离且连续的两块内存)或者“元空间”(JDK1.8 版本,“元空间”和“堆内存”是物理内存相互隔离且不连续的两块内存,“元空间”占用的本地物理内存)。虽然“元空间”取代“永久代”程序启动和运行速度 降低了(不超过 1%),但是更深层次换来的是将 HotSpot 和JRockit 的代码进行合并,同时提供更高的安全保障 (避免 OOM 异常)。

2.1 堆对象内存布局

在这里插入图片描述
HotSpot 虚拟机中对象存储分成三块区域,即,对象头、实例数据、对齐填充:

  • 对象头:对象头记录对象的信息,包括哈希码,分代年龄,锁状态标志,元数据内存地址,数组长度。
    在这里插入图片描述
  • 实例数据:存储对象自身定义的数据。
  • 对齐填充:为了对齐填充的额外数据。

2.2 偏向锁、轻量级锁及重量级锁

Java对象头是实现synchronized锁对象的基础,synchronized使用的锁对象是存储在 Java对象头里面。synchronized锁的4中状态:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态(级别从低到高)。
在这里插入图片描述
在这里插入图片描述

3、线程私有范围

线程私有范围划分为“虚拟机栈”、“本地方法栈”和“程序计数器”三大部分。“虚拟机栈”是Java方法执行的线程内存模型,“虚拟机栈”的生命周期和线程一致,每个线程创建时都会创建一个“虚拟机栈”。“虚拟机栈”保存着一个个“栈帧”,每个“栈帧”对应一个方法,“栈帧”是“虚拟机栈”的存储单位;“本地方法栈”管理本地方法的调用,并不是所有的JVM 都支持本地方法(因为 JVM 规范并没有明确要求“本地方法栈”的使用语言、具体实现方式、数据结构等。如果 JVM 产品不打算支持 native 方法,也可以无需实现“本地方法栈”),有一些 JVM(如 HotSpot)将“虚拟机栈”和“本地方法栈”合并实现;“程序计数器”是一块非常小的内存空间,可以看做是当前线程执行字节码的行号指示器,每个线程都有一个独立的“程序计数器”,因此“程序计数器”是线程私有的一块空间,此外,“程序计数器”是JVM 机规定的唯一不会发生内存溢出的区域

3.1 栈帧

“栈帧”是用于支持虚拟机进行方法调用方法执行的数据结构。它是虚拟机运行时数据区的虚拟机栈的组成元素(注意:递归调用同一个方法,调用一次就会产生一个栈帧)。“栈帧”存储了方法的局部变量表、操作数栈、动态链接和方法的返回地址等信息。每一个方法从调用开始直至执行完成的过程,都对应的一个“栈帧” 在“虚拟机栈”里入栈和出栈的过程。
在这里插入图片描述

  • 局部变量表:局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序编译为 Class 文件时,就在方法的 Code 属性的 max_locals 数据项中确定了该方法所需要分配的最大容量。局部变量表的容量以变量槽为最小单位。
  • 操作数栈:在方法执行的过程中,根据字节码指令(在 IntelliJ IDEA 中安装 jclasslib bytecode viewer插件可查看 java 类的字节码指令)往栈中写入数据或取出数据,即入栈或出栈(比如下方的 push、load 操作就是入栈,store 操作就是出栈)。主要用于保存计算过程中间结果,同时作为计算过程变量临时的存储空间。 在 Java 程序编译为 Class 文件时,就在方法的 Code 属性的 max_stack 数据项中确定了该方法所需要分配的最大栈深度
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 动态链接:指向运行时常量池或该“栈帧”所属方法的引用,那么包含这个引用的目的就是为了支持当前方法的代码能够实现动态链接(比如 invokedynamic、invokevirtual、invokespecial 等字节码指令)。
    在这里插入图片描述
    在这里插入图片描述
  • 返回地址:方法有两种退出方式,第一种是遇到方法返回指令,方法正常退出,第二种是方法执行过程遇到 异常,并且方法内不能处理,导致方法非正常退出,无论采用哪一种退出方式,方法退出后都要返回被调用 的位置。
  • 帧数据区:其实栈帧中还允许携带与JVM实现相关的一些附加信息,当然这个并不一定存在。例如,对程 序调试提供支持的信息。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值