【基础篇】九、程序计数器 JVM栈

文章目录

  • 0、运行时数据区域
  • 1、程序计数器
  • 2、JVM栈
  • 3、JVM栈--栈帧--局部变量表
  • 4、JVM栈--栈帧--操作数栈
  • 5、JVM栈--栈帧--桢数据
  • 6、栈溢出
  • 7、设置栈空间大小
  • 8、本地方法栈

0、运行时数据区域

在这里插入图片描述

JVM结构里,类加载器下来,到了运行时数据区域,即Java程序运行时,JVM管理的内存区域,其又分为:

在这里插入图片描述

栈这里可以细划分为两部分:

  • Java虚拟机栈:保存在Java中的方法
  • 本地方法栈:保存的native方法,c++实现的那些

1、程序计数器

程序计数器(Program Counter Register)也叫PC寄存器,每个线程会通过它来记录接下来要执行的的字节码指令的地址

在这里插入图片描述

举个例子:

在这里插入图片描述

类加载阶段,类加载器将字节码指令读到内存中后,将原来的偏移量改为内存地址,每条字节码指令都对应一个内存地址

在这里插入图片描述

执行完当前这一条指令后,JVM的执行引擎(JIT、解释器等)根据程序计数器中记录的数据,就拿到了接下来要执行的指令的地址。

在这里插入图片描述

多线程下,CPU从线程A切换到线程B,得知道线程B之前解释执行到哪一句指令了,此时JVM的程序计数器就发挥作用了

在这里插入图片描述

2、JVM栈

JVM的栈采用栈的数据结构,保存方法调用的基本数据,先进后出,其中,每一个调用的方法用一个叫栈帧的东西存。

如下图,流程为:

main入栈
study入栈
eat入栈
eat出栈.....
sleep入栈
sleep出栈.....
study出栈.....
main出栈.....
执行结束!

在这里插入图片描述

断点打在C方法里,看下IDEA中debug的栈信息,点击栈里的每个方法,跳到当前该方法执行在的那一行:

在这里插入图片描述

修改程序,让C程序抛出异常:

public class FrameDemo{
	
	public static void main(String[] args){
		A();
	}
	public static void A(){
		System.out.println("A执行了...");
		B();
	}
	public static void B(){
		System.out.println("B执行了...");
		C();
	}
	public static void C(){
		System.out.println("C执行了...");
		throw new RuntimeException("测试");   //异常
	}
}

可以发现,结果里也展示了异常发生时的栈信息,以及每个方法具体执行到哪一行了:

在这里插入图片描述

JVM的栈随着线程的创建而创建,也随着线程的销毁而回收,每个线程都有一个自己的JVM栈

在这里插入图片描述

3、JVM栈–栈帧–局部变量表

栈里的一个个栈帧,由三部分构成:

在这里插入图片描述

局部变量表用来存方法执行过程中的所有局部变量,类被编译成字节码时,局部变量表的内容就确定了:

在这里插入图片描述

想访问一个变量,自然是要在它声明定义之后,所以局部变量表里的起始PC就是保存了从哪一行字节码指令开始,可以访问这个变量,对于变量i,其值就为2。而长度字段为3,即代表在2.3.4这三行里可以访问i。总之就是通过局部变量表控制可以访问每个变量的范围。 是字节码文件中的局部变量表,它的作用是做安全性上的校验,比如变量的生效范围。

在这里插入图片描述

而栈帧自己的局部变量表就是一个数组,数组的每个位置叫槽slot,long和double类型占用两个槽,其他类型占用一个槽。 如上图,i占0号位,一个槽,后面long类型的j则占两个。再看字节码文件里局部变量表中的序号,其实就是这个局部变量i,在栈帧的局部变量表的起始槽的编号。

在这里插入图片描述

实例方法中的序号为0的位置存放的是this,指的是当前调用方法的对象,运行时会在内存中存放实例对象
的地址。

在这里插入图片描述

局部变量表也会存方法的形参,且顺序与形参顺序一致。

一句话,局部变量表中存的是实例方法的this对象、方法的形参、方法体中声明的局部变量

注意,局部变量表的槽可以重复使用,一旦某个局部变量不再生效,当前槽就可以再次被使用

public void test4(int k,int m){
	
	{
		int a = 1;
		int b = 2;
	}
	{
		int c = 1;
	}
	int i = 0;
	int j = 1;
}

执行完b=2时,栈帧的局部变量表长这样:

在这里插入图片描述

再往下走,字节码为:

iconst_1
istore_3

即把字面量1放入了3号槽,复用了a变量的槽。同理往下推,最终的局部变量表长这样:

在这里插入图片描述

因此,上面的代码在其栈帧的局部变量表中会占用6个槽,而不是简单的1+1+1 +1+1 +1 +1+2 = 9

4、JVM栈–栈帧–操作数栈

  • 操作数栈是JVM在执行指令时,用来存放中间数据的区域
  • 栈的数据结构,压栈+弹栈
  • 编译器就可决定操作数栈的最大深度,用jclasslib验证:
    在这里插入图片描述

分析下以上源码的字节码:

在这里插入图片描述

操作数栈的变化过程如下:

在这里插入图片描述
在这里插入图片描述

最终状态:
在这里插入图片描述

可以看到,整个过程中,操作数栈里最多有两个数据,即操作数栈的最大深度为2,此时创建栈帧时,创建深度为2的操作数栈即可。

5、JVM栈–栈帧–桢数据

桢数据主要含:

  • 动态链接
  • 方法出口
  • 异常表引用
Part1:动态链接

在这里插入图片描述
当前类的字节码中引用了别的类的方法或属性,要将符号引用(#10)转成内存地址。动态链接就保存了编号到运行时常量池的内存地址的映射关系。

Part2:方法出口

在栈帧的桢数据中,存放了上一个方法的地址(sleep方法的桢数据有study方法执行到哪一行的信息)
在这里插入图片描述

当方法正常结束或发生异常结束时,当前栈帧被弹出,同时程序计数器指向上一个栈帧的下一条指令地址:

在这里插入图片描述

Part3:异常表引用

存放异常捕获的范围,以及这个范围发生异常后跳哪一行。 eg:看异常表的第一行,从起始PC 0到结束PC 2,如果发生异常,就跳转到第7行,astore_0即把捕获的异常对象e放到局部变量表中,因为catch块中大概率会用到e对象

在这里插入图片描述

6、栈溢出

一个线程的栈里,栈帧过多,占用的内存到达了分配的最大值,再入栈就会StackOverflowError,即栈溢出。

在这里插入图片描述

如下为OpenJDK8里JVM的源码,不指定栈的大小时,JVM创建的是一个默认大小的栈,不同的操作系统里,这个默认值也不同。

在这里插入图片描述

用无停止条件的递归来看栈溢出:

public static int count = 0;
//递归方法调用自己
 public static void recursion(){
 
	 System.out.println(++count);
	 
	 recursion();
	 
 }

在这里插入图片描述
运行,默认情况下,main线程的栈里放了大约10473个栈帧:

在这里插入图片描述

7、设置栈空间大小

添加JVM参数:

-Xss栈大小

单位默认是byte字节(默认,必须是 1024 的倍数),可选k或者K(KB)、m或者M(MB)、g或者G(GB)

eg:
-Xss1048576 
-Xss1024K 
-Xss1m
-Xss1g

在这里插入图片描述
设置线程栈空间大小,还可以用另一个参数:

//注意等号
 -XX:ThreadStackSize=1024

HotSpot对栈空间的大小有范围限制,Windows(64位)下的JDK8测试最小值为180k,最大值为1024m,超过这个范围,即使设置了也不会生效。

//无效
-Xss1k
-Xss1025m

当然,局部变量过多(栈帧局部变量表大)、操作数栈深度大,在相同大小下,能存的栈帧数量也就少了。最后,工作中,该值建议用

-Xss256k

8、本地方法栈

JVM栈中存的是Java方法的栈桢,本地方法栈里存的则是native本地方法的栈帧。不过在HotSpot虚拟机中,JVM栈和本地方法栈实现上使用了同一个栈空间。

在这里插入图片描述

如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/287680.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux用shell脚本执行乘法口诀表的两种方式

#!/bin/bash # *********************************************************# # # # * Author : 藻头男 # # * QQ邮箱 : 2322944912qq.com # …

数据库选择题 (期末复习)

2015期末 1、在数据库中,下列说法(A)是不正确的 A. 数据库避免了一切数据的重复 B. 数据库可以实现数据的独立性 C. 数据库中的数据可以共享 D. 数据库减少了数据冗余 2、事务日志一般用于保存(C) A. 程序运行过程 B…

怎么规划自己的现货白银交易生涯?

做现货白银交易不是儿戏的,应该对自己的生涯进行有效的规划,那么投资者如何规划自己的交易生涯呢?下面,我们将从资金管理和增长的角度来讨论一下。 首先我们讨论一下,在现货白银交易中应该如何管理盈利。我们应该要注意…

ByteTrack算法流程的简单示例

ByteTrack ByteTrack算法是将t帧检测出来的检测框集合 D {\mathcal{D}} D 和t-1帧预测轨迹集合 T ~ t − 1 {\tilde{T}_{t-1}} T~t−1​ 进行匹配关联得到t帧的轨迹集合 T t {T_{t}} Tt​。 首先使用检测器检测t帧的图像得到检测框集合 D {\mathcal{D}} D,再…

Oracle-增删改查

增删改 处理日期 oracle 处理date 类型 必须使用 to_date 函数或 sysdate oracle 与 mysql 处理 date 的区别mysql 中的 date 类型 只 支持 年月日, 使用 2000-10-01 oracle 中 date 类型 包含 年月日时分秒, 使用 to_date 函数to_date(1999-10-15,yyyy-MM-dd)​orac…

思科校园网搭建及配置综合小型实验

思科校园网搭建及配置综合小型实验 实验拓扑配置步骤配置聚合链路配置VTP,vlan域模板第一步 配置二层VLAN第二步 配置生成树第三步 配置相关IP地址第四步 配置DHCP及DHCP中继第五步 配置三层的网关冗余协议 双机热备及OSPF第六步 配置静态路由,NAT地址转换及其他配置…

STM32 ESP8266 物联网智能温室大棚 (附源码 PCB 原理图 设计文档)

资料下载: https://download.csdn.net/download/vvoennvv/88680924 一、概述 本系统以STM32F103C8T6单片机为主控芯片,采用相关传感器构建系统硬件电路。其中使用DHT11温湿度传感器对温度和湿度的采集,MQ-7一氧化碳传感器检测CO浓度,GP2Y101…

深度思考,AI项目的人工智能到底引领的是什么?

项目深度思考,人工智能到底引领的是什么? 人工智能引领技术之舞:项目深度思考项目背景:人工智能的魔法时代技术选择的深度思考:AI大决战团队协作的深度思考:AI联盟大会用户体验的深度思考:AI之光…

Redis命令---String篇 (超全)

目录 1.Redis Setnx 命令 - 只有在 key 不存在时设置 key 的值。简介语法可用版本: > 1.0.0返回值: 设置成功,返回 1 。 设置失败,返回 0 。 示例 2.Redis Getrange 命令 - 返回 key 中字符串值的子字符简介语法可用版本: > 2.4.0返回值: 截取得到…

Sigmaplot14安装包下载及安装教程

Sigmaplot 14下载链接:https://docs.qq.com/doc/DUnR0QmVzRVRXdGdB 1.鼠标右键解压到“Sigmaplot 14.0” 2.选中Sigmaplot14.0,鼠标右击选择“以管理员身份运行” 3.点击“Next” 4.选择I accept the terms of the license agreement,点击“N…

九州金榜|家庭教育中如何让孩子听话

心理学上有个专业名词叫做超限效应,是说如果外来刺激过多、过强或者是作用时间过久,就会让人感觉不耐烦,甚至是产生逆反心理。 这就是为什么现实生活中,很多父母就一件事唠叨无数遍,孩子依然不为所动的原因所在。 九…

Java获取windows操作系统基本信息

Java可以通过使用System类中的一些属性和方法来获取Windows操作系统的基本信息。以下是一些示例代码: public class WindowsInfo {public static void main(String[] args) {// 获取操作系统名称String osName System.getProperty("os.name");System.ou…

网络安全—IPSec安全策略

文章目录 网络拓扑添加策略ESP添加筛选器添加筛选器的操作另一台主机设置 AH 使用Windows Server 2003系统 网络拓扑 client1 IP 192.168.17.105client2 IP 192.168.17.106 只要保证两个主机在同一网段接口,即互相ping通即可完成策略的实现 下面的所有通讯都只是…

pytorch学习笔记

torchvision处理图像的 pytorch官网上看数据集的包,COCO数据集目标检测、语义分割,cifar物体识别 预训练好的模型 这个模块是图片的处理 root-位置,train-创建的true是个训练集,transform 前面是输出图片的数据类型,“…

在较高时间周期 这些现货黄金投资法值得一用

以日线图和周线图为代表的较高时间周期,一直是投资者很少利用的。之所以这么说,不是说投资者不会在日线图上分析,而是很少利用日线图交易。一来持仓过夜,会有相关的费用产生。二来很多人做现货黄金以短线为主。其实这种较高的时间…

【解决|三方工具】导入 XChart 后提示丢失关于 TMPPro 工具引用

开发平台:Unity 2021 版本 插件版本:XChart 3.0:官方文档 - https://github.com/XCharts-Team/XCharts   问题描述 导入 XChart 插件至 Unity 中出现 目录:Component、Theme 等提示丢失 TMPPro(TextMeshPro 工具&…

如何在ArcGIS Pro中指定坐标系

在进行制图的时候,为了实现某些特定的效果,需要指定特定的坐标系,但是现有的数据可能不是所需要的坐标系,这时候就需要对现有的数据坐标系进行处理,这里为大家介绍一下ArcGIS Pro中指定坐标系的方法,希望能…

Java经典框架之SpringSecurity

SpringSecurity Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. SpringSecurity基本应用…

宏集七轴机械臂,以精准力控实现柔性抛光打磨!

(一)行业背景 传统的手工抛光打磨存在劳动强度高、抛光效果不稳定、难以处理复杂形状、安全风险和无法满足高质量要求等痛点。因此,应用工业机器人进行自动化表面精加工的技术随之崛起。 然而,打磨抛光领域一直难以实现全面的自动…

深入了解隧道代理HTTP的协议与技术细节

隧道代理HTTP,作为一种网络通信的桥梁技术,其背后的协议与技术细节承载着网络世界的无尽奥秘。对于技术人员而言,深入了解这些细节,不仅有助于优化网络性能,还能为网络安全提供坚实的保障。 一、隧道代理HTTP的协议基…