[JVM] Java虚拟机栈

article/2025/8/22 17:10:05

1. 概念

Java虚拟机栈(Java Virtual Machine Stacks)是线程私有的栈使用的内存不需要保证是连续的栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用至执行完成的过程,都对应着一个栈帧在虚拟机栈里从入栈到出栈的过程。

Java虚拟机规范即允许Java虚拟机栈被实现成固定大小(-Xss),也允许通过计算结果动态来扩容和收缩大小。如果采用固定大小的Java虚拟机栈,那每个线程的Java虚拟机栈容量可以在线程创建的时候就已经确定,并写入方法表的Code属性之中。

 

Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素。栈帧存储了方法的局部变量表操作数栈动态连接方法返回地址等信息。

在运行时的线程中,只有当前栈帧有效(Java虚拟机栈中栈顶的栈帧),与当前栈帧相关联的方法称为当前方法。每调用一个新的方法,被调用方法对应的栈帧就会被放到栈顶(入栈),也就是成为新的当前栈帧。当一个方法执行完成退出的时候,此方法对应的栈帧也相应销毁(出栈)。

2. 局部变量表

2.1变量槽

局部变量表的容量以变量槽(Variable Slot)为最小单位,不过Java虚拟机规范中并没有明确规定每个Slot所占据的内存空间大小Java虚拟机规范允许Slot的长度可以随着处理器、操作系统或者虚拟机的不同而发生变化。对于64位的数据类型,虚拟机会以高位在前的方式为其分配两个连续的Slot空间。即long和double两种类型。做法是将long和double类型速写分割为32位读写的做法使用第n和第n+1两个Slot来表示。

2.2 局部变量表特性 

如果是实例方法(非static方法),那么局部变量表中的第0位索引的Slot默认是用来传递方法所属对象实例的引用,在方法中可以通过关键字this来访问这个隐含的参数。其余参数按照参数表的顺序来排列,占用从1开始的局部变量Slot,参数表分配完毕后,再根据方法体内部定义的变量顺序和作用域分配其余的Slot。简而言之如图所示,static方法在变量表中没有this参数,实例方法有this,且序号靠前。

 

 局部变量表中的Slot是可重用的,方法体中定义的变量,其作用域并不一定会覆盖整个方法体,如果当前字节码程序计数器的值已经超过了某个变量的作用域,那么这个变量相应的Slot就可以交给其他变量去使用,节省栈空间,但也有可能会影响到系统的垃圾收集行为。局部变量在使用完以后它的槽会让给其他变量重复使用。如图中b变量的槽使用完后,c变量也使用了序号2的槽,达到了节约空间的效果。

 

变量槽的重复使用会影响垃圾收集行为,在垃圾收集时候会对象无法回收的情况情况。如图中左为回收对象失败,经过修改后如图中右边顺利回收了对象。

placeholder能否被回收的根本原因就是:局部变量表中的变量槽是否还存有关于placeholder数组对象的引用。首先需要代码离开了placeholder的作用域。但由于没有发生过任何对局部变量表的读写操作,placeholder原本所占用的变量槽还没有被其他变量所复用,所以作为GC Roots一部分的局部变量表仍然保持着对它的关联。这种关联没有被及时打断,绝大部分情况下影响都很轻微。但如果遇到一个方法,其后面的代码有一些耗时很长的操作,而前面又定义了占用了大量内存但实际上已经不会再使用的变量,手动将其设置为null值(用来代替那句int a=0,把变量对应的局部变量槽清空)。

 

3. 操作数栈

操作数栈(Operand Stack)也常称为操作栈,它是一个后入先出栈(LIFO)。同局部变量表一样,操作数栈的最大深度也在编译的时候写入到方法的Code属性的max_stacks数据项中

另外在概念模型中,两个不同栈帧作为不同方法的虚拟机栈的元素,是完全相互独立的。但是在大多虚拟机的实现里都会进行一些优化处理,令两个栈帧出现一部分重叠。让下面栈帧的部分操作数栈与上面栈帧的部分局部变量表重叠在一起,这样做不仅节约了一些空间,更重要的是在进行方法调用时就可以直接共用一部分数据,无须进行额外的参数复制传递了,重叠的过程如图所示。

4.动态链接

Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数。这些符号引用一部分会在类加载阶段或者第一次使用的时候就被转化为直接引用,这种转化被称为静态解析。另外一部分将在每一次运行期间都转化为直接引用,这部分就称为动态连接。动态链接保存的是指向方法区常量池中该方法的引用。

5.方法返回地址

对象引用(reference类型,它并不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址)。

6.本地方法栈

本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。本地方法栈服务的对象是JVM执行的native方法,其就是一个java调用非java代码的接口,作用是与操作系统和外部环境交互。

如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈。当C程序调用一个C函数时,其栈操作都是确定的。传递给该函数的参数以某个确定的顺序压入栈,它的返回值也以确定的方式传回调用者。同样,这就是虚拟机实现中本地方法栈的行为。

 7.程序计数器

程序计数器,(Program Counter Register)每一个线程都有唯一对应的程序计数器是线程私有的,它内存空间小,几乎可以忽略不记,是运行速度最快的存储区域。如图2-1所示,程序计数器是一个记录着当前线程所执行的字节码的行号指示器

 


http://chatgpt.dhexx.cn/article/0dLaJgpy.shtml

相关文章

【JVM】Java虚拟机简介

【JVM】Java虚拟机简介 我们看中的并非Java语言,而是JVM。——Java之父James Gosling Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制。 JVM实现了Java语言最重要的特征:即平台无关性。这是因…

JAVA虚拟机概述

本博客内容为《深入理解Java虚拟机:JVM高级特性与最佳实践》的阅读笔记。 1 Java技术体系 仅从传统意义上来看,Sun官方所定义的Java技术体系包括以下几个组成部分: Java程序语言设计各种硬件平台上的Java虚拟机Class文件格式Java API类库来…

详解Java虚拟机

资料来源:尚硅谷宋红康JVM全套教程(详解java虚拟机)_哔哩哔哩_bilibili 1.JVM与Java体系结构 1.1. 前言 如果我们把核心类库的API比做数学公式的话,那么Java虚拟机的知识就好比公式的推导过程。 计算机系统体系对我们来说越来越远…

java虚拟机到底是什么

转自:http://blog.csdn.net/zhangjg_blog/article/details/20380971 http://blog.hesey.net/2011/04/introduction-to-java-virtual-machine.html 虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架…

深入理解Java虚拟机到底是什么

什么是Java虚拟机 作为一个Java程序员,我们每天都在写Java代码,我们写的代码都是在一个叫做Java虚拟机的东西上执行的。但是如果要问什么是虚拟机,恐怕很多人就会模棱两可了。在本文中,我会写下我对虚拟机的理解。因为能力所限&am…

java虚拟机(JVM)

一、虚拟机的组成 虚拟机的组成主要有:方法区、堆都为线程共享区域,有线程安全问题。 栈、本地方法栈、程序计数器为线程的独享区域,不存在线程安全问题。 注:JVM的调优主要是针对堆和栈进行的 1.1:运行时数据区域 …

JVM——Java虚拟机架构

0. 前言 Java虚拟机(Java virtualmachine)实现了Java语言最重要的特征:即平台无关性。 平台无关性原理:编译后的 Java程序(.class文件)由 JVM执行。JVM屏蔽了与具体平台相关的信息,使程序可以…

深入理解Java虚拟机

前言 JVM是什么? JVM(Java Virtual Machine,Java 虚拟机)顾名思义就是用来执行 Java 程序的“虚拟主机”,实际的工作是将编译生成的.class 文件(字节码)翻译成底层操作系统可以运行的机器码并…

一文彻底了解JVM

目录 JVM内存结构 GC算法和收集器 JDK性能调优监控工具 GC调优 JVM内存结构 类加载机制 Java运行时编译源码(.java)成字节码,由jre运行。jre由java虚拟机实现。JVM分析字节码,后解释并执行。 1、全盘负责委托机制 当一个ClassLoader加载一个类的时…

通俗易懂理解JAVA虚拟机

目录 前言 一、什么是JAVA虚拟机(JVM) 二、内存结构 1.程序计数器 2.虚拟机栈 3.本地方法栈 4.堆 5.方法区(元数据区) 6、执行引擎 7、直接内存 三、垃圾回收 1.如何判断对象可以回收, 2.垃圾回收算法…

Java虚拟机(JVM)你只要看这一篇就够了!

本文是学习了《深入理解Java虚拟机》之后的总结,主要内容都来自于书中,也有作者的一些理解。一是为了梳理知识点,归纳总结,二是为了分享交流,如有错误之处还望指出。 用XMind画了一张导图(源文件对部分节点…

简单的文本编辑器

今天应同学的需求写了一个文本编辑器可以简单的时间文本的打开、删除、显示、查找、插入的简单功能 C语言代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #define MAX 10000 #include <stri…

使用vue的富文本编辑器操作

使用vue的富文本编辑器操作 vue的富文本编辑器使用以及多图片文件上传与回显 一. vue-quill-edit 1. 安装vue的富文本 cd 当前的vue项目路径 npm install quill --save npm install vue-quill-editor --save2. 在页面中引入vue的富文本 //引入Vue的ueditor的资源 import {q…

Ckeditor富文本编辑器

开发工具与关键技术&#xff1a; MVC 撰写时间&#xff1a;2021/9/28 下面我们讲Ckeditor富文本编辑器的使用&#xff1b; 要使用Ckeditor富文本编辑器&#xff0c;需要在Ckeditor官网中下载js插件&#xff0c;下载后会得到一个ckeditor文件&#xff1a; 其中包含以下文件&am…

[web]前端富文本编辑器

关于富文本编辑器 在HTML中&#xff0c;用于输入文本的只是<input type"text"/>和<textarea>这2种标签&#xff0c;这些标签都只能输入纯文本&#xff0c;不可以对输入的内容进行编排&#xff01; 在实际应用时&#xff0c;例如发布文章&#xff0c;需要…

深入浅出富文本编辑器

‍ ‍大厂技术 坚持周更 精选好文 编辑器介绍 常见的富文本编辑器现实方式可以分成两大类&#xff0c;分别是用 textarea 和 contenteditable 来实现。 textarea 结构简单使用方便&#xff0c;一些文本格式和复杂的样式难以实现&#xff0c;推荐仅在对编辑要求不高的场景使用…

推荐几个非常不错的富文本编辑器

1、wangEditor——基于javascript和css开发的 Web富文本编辑器&#xff0c; 轻量、简洁、界面美观、易用、开源免费。 界面截图&#xff1a;官网地址 2、TinyMCE——TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器&#xff0c;由JavaScript写成。它对IE6和Firefox1.5都有…

vue使用富文本编辑器vue-quill-editor

问题描述&#xff1a; 我们在开发过程中经常会遇到使用富文本编辑器进行操作&#xff0c;当前插件市场上关于富文本的编辑器挺多的&#xff0c;我们就不一一个介绍了&#xff0c;现在我们主要讲解一些vue-quill-editor富文本编辑器的使用操作和注意事项。 效果图 具体操作使用…

LayUI - 富文本编辑器

一个做后端的猿&#xff0c;难免用到LayUI&#xff0c;首先在这里&#xff0c;不推荐使用&#xff0c;坑多 我这里用的是layui-v2.5.7版本 一、富文本编辑器 缺点&#xff1a;功能太少&#xff0c;只能满足简单需求&#xff0c;只有下面这几个功能 废话少说&#xff0c;直接丢…

最佳文本编辑器

原文&#xff1a; donationcoder.com  译者&#xff1a; xbeta善用佳软  说明&#xff1a;仅做翻译&#xff0c;忠实原文。不代表同意文中观点&#xff08;xbeta认为最好的编辑器为VIM&#xff09;。 最佳文本编辑器 当前&#xff0c;好用的文本编辑器比比皆是——无论商…