从JVM底层原理分析数值交换那些事·Java大数据高级架构师

YOLOv8有效涨点,增强型 YOLOV8 与多尺度注意力机制特征融合,附代码,详细步骤 在本实验中,我们通过将双层路由注意(BRA)、广义特征金字塔网络(GFPN)和第四检测头结合到YOLOv8中,开发了一种新颖的BGF-YOLO架构。BGF-YOLO 包含注意力机制,可以更多地关注重要特征,特征金字塔网络可以通过将高级语义特征与空间细节合并来丰富特征表示。此外,我们研究了不同的注意力机制和特征融合、检测头架构对检测准确性的影响。实验结果表明,与YOLOv8x相比,BGF-YOLO的mAP50增加了4.7%。 阅读详情

基础数据类型交换

这个话题,需要从最最基础的一道题目说起,看题目:以下代码a和b的值会交换么:

    public static void main(String[] args) {
        int a = 1, b = 2;
        swapInt(a, b);
        System.out.println("a=" + a + " , b=" + b);
    }
    private static void swapInt(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }    

结果估计大家都知道,a和b并没有交换:

integerA=1 , integerB=2

但是原因呢?先看这张图,先来说说Java虚拟机的结构:

从JVM底层原理分析数值交换那些事

运行时区域主要分为:

  • 线程私有:
    • 程序计数器:Program Count Register,线程私有,没有垃圾回收
    • 虚拟机栈:VM Stack,线程私有,没有垃圾回收
    • 本地方法栈:Native Method Stack,线程私有,没有垃圾回收
  • 线程共享:
    • 方法区:Method Area,以HotSpot为例,JDK1.8后元空间取代方法区,有垃圾回收。
    • 堆:Heap,垃圾回收最重要的地方。

和这个代码相关的主要是虚拟机栈,也叫方法栈,是每一个线程私有的。
生命周期和线程一样,主要是记录该线程Java方法执行的内存模型。虚拟机栈里面放着好多栈帧。注意虚拟机栈,对应是Java方法,不包括本地方法。

一个Java方法执行会创建一个栈帧,一个栈帧主要存储:

  • 局部变量表
  • 操作数栈
  • 动态链接
  • 方法出口
    每一个方法调用的时候,就相当于将一个栈帧放到虚拟机栈中(入栈),方法执行完成的时候,就是对应着将该栈帧从虚拟机栈中弹出(出栈)。

每一个线程有一个自己的虚拟机栈,这样就不会混起来,如果不是线程独立的话,会造成调用混乱。

大家平时说的java内存分为堆和栈,其实就是为了简便的不太严谨的说法,他们说的栈一般是指虚拟机栈,或者虚拟机栈里面的局部变量表。

局部变量表一般存放着以下数据:

  • 基本数据类型(boolean,byte,char,short,int,float,long,double)
  • 对象引用(reference类型,不一定是对象本身,可能是一个对象起始地址的引用指针,或者一个代表对象的句柄,或者与对象相关的位置)
  • returAddress(指向了一条字节码指令的地址)

局部变量表内存大小编译期间确定,运行期间不会变化。空间衡量我们叫Slot(局部变量空间)。64位的long和double会占用2个Slot,其他的数据类型占用1个Slot。

上面的方法调用的时候,实际上栈帧是这样的,调用main()函数的时候,会往虚拟机栈里面放一个栈帧,栈帧里面我们主要关注局部变量表,传入的参数也会当成局部变量,所以第一个局部变量就是参数args,由于这个是static方法,也就是类方法,所以不会有当前对象的指针。

从JVM底层原理分析数值交换那些事

如果是普通方法,那么局部变量表里面会多出一个局部变量this。

如何证明这个东西真的存在呢?我们大概看看字节码,因为局部变量在编译的时候就确定了,运行期不会变化的。下面是IDEA插件jclasslib查看的:

从JVM底层原理分析数值交换那些事

上面的图,我们在main()方法的局部变量表中,确实看到了三个变量:args,a,b。

那在main()方法里面调用了swapInt(a, b)呢?

那堆栈里面就会放入swapInt(a,b)的栈帧,相当于把a和b局部变量复制了一份,变成下面这样,由于里面一共有三个局部变量:

  • a:参数
  • b:参数
  • temp:函数内临时变量

a和b交换之后,其实swapInt(a,b)的栈帧变了,a变为2,b变为1,但是main()栈帧的a和b并没有变。

从JVM底层原理分析数值交换那些事

那同样来从字节码看,会发现确实有3个局部变量在局部变量表内,并且他们的数值都是int类型。

从JVM底层原理分析数值交换那些事

而swap(a,b)执行结束之后,该方法的堆栈会被弹出虚拟机栈,此时虚拟机栈又剩下main()方法的栈帧,由于基础数据类型的数值相当于存在局部变量中,swap(a,b)栈帧中的局部变量不会影响main()方法的栈帧中的局部变量,所以,就算你在swap(a,b)中交换了,也不会变。

从JVM底层原理分析数值交换那些事

基础包装数据类型交换

将上面的数据类型换成包装类型,也就是Integer对象,结果会如何呢?

    public static void main(String[] args) {
        Integer a = 1, b = 2;
        swapInteger(a, b);
        System.out.println("a=" + a + " , b=" + b);
    }
    private static void swapInteger(Integer a, Integer b) {
        Integer temp = a;
        a = b;
        b = temp;
    }

结果还是一样,交换无效:

a=1 , b=2

这个怎么解释呢?

对象类型已经不是基础数据类型了,局部变量表里面的变量存的不是数值,而是对象的引用了。先用jclasslib查看一下字节码里面的局部变量表,发现其实和上面差不多,只是描述符变了,从int变成Integer。

从JVM底层原理分析数值交换那些事

从JVM底层原理分析数值交换那些事

但是和基础数据类型不同的是,局部变量里面存在的其实是堆里面真实的对象的引用地址,通过这个地址可以找到对象,比如,执行main()函数的时候,虚拟机栈如下:

假设 a 里面记录的是 1001 ,去堆里面找地址为 1001 的对象,对象里面存了数值1。b 里面记录的是 1002 ,去堆里面找地址为 1002 的对象,对象里面存了数值2。

从JVM底层原理分析数值交换那些事

而执行swapInteger(a,b)的时候,但是还没有交换的时候,相当于把 局部变量复制了一份:

从JVM底层原理分析数值交换那些事

而两者交换之后,其实是SwapInteger(a,b)栈帧中的a里面存的地址引用变了,指向了b,但是b里面的,指向了a。

从JVM底层原理分析数值交换那些事

而swapInteger()执行结束之后,其实swapInteger(a,b)的栈帧会退出虚拟机栈,只留下main()的栈帧。

从JVM底层原理分析数值交换那些事

这时候,a其实还是指向1,b还是指向2,因此,交换是没有起效果的。

String,StringBuffer,自定义对象交换

一开始,我以为String不会变是因为final修饰的,但是实际上,不变是对的,但是不是这个原因。原因和上面的差不多。

String是不可变的,只是说堆/常量池内的数据本身不可变。但是引用还是一样的,和上面分析的Integer一样。

从JVM底层原理分析数值交换那些事

其实StringBuffer和自定义对象都一样,局部变量表内存在的都是引用,所以交换是不会变化的,因为swap()函数内的栈帧不会影响调用它的函数的栈帧。

不行我们来测试一下,用事实说话:

   public static void main(String[] args) {
        String a = new String("1"), b = new String("2");
        swapString(a, b);
        System.out.println("a=" + a + " , b=" + b);

        StringBuffer stringBuffer1 = new StringBuffer("1"), stringBuffer2 = new StringBuffer("2");
        swapStringBuffer(stringBuffer1, stringBuffer2);
        System.out.println("stringBuffer1=" + stringBuffer1 + " , stringBuffer2=" + stringBuffer2);

        Person person1 = new Person("person1");
        Person person2 = new Person("person2");
        swapObject(person1,person2);
        System.out.println("person1=" + person1 + " , person2=" + person2);
    }

    private static void swapString(String s1,String s2){
        String temp = s1;
        s1 = s2;
        s2 = temp;
    }

    private static void swapStringBuffer(StringBuffer s1,StringBuffer s2){
        StringBuffer temp = s1;
        s1 = s2;
        s2 = temp;
    }

    private static void swapObject(Person p1,Person p2){
        Person temp = p1;
        p1 = p2;
        p2 = temp;
    }


class Person{
    String name;

    public Person(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }
}

执行结果,证明交换确实没有起效果。

a=1 , b=2
stringBuffer1=1 , stringBuffer2=2
person1=Person{name='person1'} , person2=Person{name='person2'}

总结

基础数据类型交换,栈帧里面存的是局部变量的数值,交换的时候,两个栈帧不会干扰,swap(a,b)执行完成退出栈帧后,main()的局部变量表还是以前的,所以不会变。

对象类型交换,栈帧里面存的是对象的地址引用,交换的时候,只是swap(a,b)的局部变量表的局部变量里面存的引用地址变化了,同样swap(a,b)执行完成退出栈帧后,main()的局部变量表还是以前的,所以不会变。

所以不管怎么交换都是不会变的。

【Segment Anything Model】十(1):利用SAM做分类任务,方法二,不放过SAM强大特征提取能力,将SAM提取到的ImageEmbedding插入到其他cnn网络中 直接黏贴复制就好'''该类定义了VGG-16的基本结构。features: 代表VGG网络的主体部分,即所有的卷积层和池化层。avgpool: 是自适应平均池化层,将特征图大小调整为7x7。classifier: 是VGG网络的分类部分,由全连接层组成。_initialize_weights(): 初始化权重的方法。 阅读详情

相关推荐

UOS系统手动添加1920x1080分辨率:xrandr命令详解与持久化配置

本文详细介绍了在UOS系统中使用xrandr命令手动添加1920x1080分辨率的方法。针对系统设置中缺失该选项的常见问题,文章提供了从识别显示设备、使用cvt生成模式、添加并切换分辨率,到通过修改.profile文件实现持久化配置的完整步骤。同时涵盖了虚拟机环境、设备名识别及排错等进阶内容,帮助用户彻底解决UOS分辨率配置难题。

weixin_29300931的博客 500

jvm内存分配过程

jvm内存分配过程 1、JVM 会试图为相关Java对象在Eden Space中初始化一块内存区域。 2、当Eden空间足够时,内存申请结束;否则到下一步。 3、JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收)。释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区。 4、Survivor区被用来作为Eden及Old的中

Linn 1万+

Android布局基础与UI设计入门:打造精美应用界面

恭喜你!现在你已经掌握了Android UI开发的基础知识,包括各种布局类型、常用控件的使用以及一些UI优化技巧。这些知识将帮助你设计出既美观又实用的Android应用界面。

m0_65382359的博客 2058

JVM详解

在JVM中堆空间划分如下图所示 上图中,刻画了Java程序运行时的堆空间,可以简述成如下2条 1.JVM中堆空间可以分成三个大区,新生代、老年代、永久代 2.新生代可以划分为三个区,Eden区,两个幸存区 在JVM运行时,可以通过配置以下参数改变整个JVM堆的配置比例 1.JVM运行时堆的大小 -Xms堆的最小值 -Xmx堆空间的最大值 2.新生代堆空间大小调整 -XX:NewS...

指尖有改变世界的力量 381

LwIP在国产MCU的落地实践:从协议栈优化到网络稳定性实战

本文详细介绍了LwIP协议栈在国产GD32F407 MCU上的移植与优化实践,涵盖硬件平台选择、驱动适配、协议栈调优和网络稳定性提升策略。通过内存管理优化、实时操作系统集成和性能测试,为工业物联网应用提供高可靠性网络通信解决方案,显著提升数据传输效率和系统稳定性。

m2n3b4v5c6的博客 270

基于ADS\HFSS\Matlab的平面带通发夹滤波器设计

写在最前面,前段时间完成了一个小项目,实现13.5~14GHz的带通滤波器,算是第一个微波项目,在老师、学长、各种大神的指点下,最终完成了指标,想来这段时间收获良多,想到老师教导的,有能力的话要尽可能帮助别人,以及网络上很少面向于小白的教程,于是决定把自己做这个小项目的经过,一些关键步骤,还有软件操作和公式讲解都发出来,供大家指正借鉴。由于我目前大三,刚学习电磁场、微波工程等等,技术实在有限,同时这样是我第一次发帖子,只能尽可能的将自己确认过正确的内容,步骤以及一些经验写出来,供大家借鉴。

likaifeng12138的博客 5223

数据交换格式——json,xml

1 数据交换格式 数据交换格式(报文/参数列表),就是客户端与服务器常用的数据交换格式xml,json,html等,常用于面向接口开发。 json:一种轻量级数据交换格式。移动端(安卓、IOS)通讯方式采用http协议+JSON格式 走restful风格。很多互联网项目都采用Http协议+JSON。占用宽带小 xml:可扩展的标记语言,重量级交换格式。因为xml比较重WebService服...

种花家的奋斗兔的博客 1446

【异常】OpenClaw LLM请求超时故障全链路排查与解决方案 LLM request timed out. 网络连接超时了

摘要: OpenClaw LLM请求超时故障是高频网络交互问题,表现为客户端在预设时间内未收到服务端响应。根因分为四类:客户端配置缺陷(如超时阈值不合理)、网络链路异常(防火墙拦截等)、服务端问题(限流/宕机)及硬件瓶颈(算力不足)。解决方案分三步: 通用排查:检查网络连通性、关闭防火墙/代理校验,调整超时阈值至60-300秒; 分场景修复:云端API需核对密钥/限流规则,本地部署需验证服务状态与硬件资源; 兜底方案:重启程序、更新版本或更换服务端点,结合日志精准定位。修复后不影响OpenClaw数据完整性

奶爸的编程之路,也就一周冷个三天 2061

数据交换过程详解

前言: 本文主要介绍数据交换过程中常用的数据交换方法和方式以及数据交换在新技术下所面对的“挑战”,方便大家深入理解数据交换过程。普元实施数据交换项目已有多年成功经验,本文也将分享大数据时代数据交换所遇到的问题和应对策略。 目录: 1、为什么要进行数据交换 2、数据交换存在的问题 3、数据交换面临的挑战 4、数据交换破解“数据孤岛” 5、总结 1.为什么要进行数据交换 企业大量的IT投资建立了众多的信息系统,但是随着信息系统的增加,各自孤立工作的信息系统将会造成大量的冗余数...

song0394的专栏 2434

080、多轴运动控制:插补器设计(螺旋线插补)

本文分享了螺旋线插补器设计的实战经验。针对五轴点胶机Z轴抖动问题,作者分析了螺旋线数学本质,提出基于归一化时间参数的速度规划方法,强调各轴严格同步的重要性。文章详细介绍了速度分解、加减速处理、嵌入式优化技巧(查表法、定点化),并总结了起点闭合、速度波动、数值处理等常见问题解决方案。最后给出5条实用建议:注重速度规划而非纯数学推导、预先仿真、保留调试接口、考虑机械谐振、防范编码器丢脉冲。通过优化插补周期、电子齿轮比和S形速度曲线,成功将设备良率从60%提升至95%。

m0_50546716的博客 87

提示词工程中的上下文隔离

已经进入context的prompt是没有办法让大模型真正的忘记的,但是可以通过prompt技巧强约束模型的后续推理中“不再使用、不再提及、不再引用”某部分提示词,这其实是一种行为抑制(behavior suppression),并不是删除。

Criss@陈磊 235

从JVM底层原理分析数值交换那些事

基础数据类型交换 这个话题,需要从最最基础的一道题目说起,看题目:以下代码a和b的值会交换么: public static void main(String[] args) { int a = 1, b = 2; swapInt(a, b); System.out.println("a=" + a + " , b=" + b); } private static void swapInt(int a, int b) {

秦怀杂货店 432

在claude code中使用glm模型出现Unable to connect to Anthropic services的解决方案

本文主要介绍了在claude code中使用glm模型出现Unable to connect to Anthropic services的解决方案,希望能对使用claude code的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 13万+

从JVM底层原理分析数值交换那些事·Java大数据高级架构师(1)

而swap(a,b)执行结束之后,该方法的堆栈会被弹出虚拟机栈,此时虚拟机栈又剩下main()方法的栈帧,由于基础数据类型的数值相当于存在局部变量中,swap(a,b)栈帧中的局部变量不会影响main()方法的栈帧中的局部变量,所以,就算你在swap(a,b)中交换了,也不会变。而两者交换之后,其实是SwapInteger(a,b)栈帧中的a里面存的地址引用变了,指向了b,但是b里面的,指向了a。一开始,我以为String不会变是因为final修饰的,但是实际上,不变是对的,但是不是这个原因。

2401_84167046的博客 809

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

从JVM底层原理分析数值交换那些事·Java大数据高级架构师(3)

而swap(a,b)执行结束之后,该方法的堆栈会被弹出虚拟机栈,此时虚拟机栈又剩下main()方法的栈帧,由于基础数据类型的数值相当于存在局部变量中,swap(a,b)栈帧中的局部变量不会影响main()方法的栈帧中的局部变量,所以,就算你在swap(a,b)中交换了,也不会变。而两者交换之后,其实是SwapInteger(a,b)栈帧中的a里面存的地址引用变了,指向了b,但是b里面的,指向了a。一开始,我以为String不会变是因为final修饰的,但是实际上,不变是对的,但是不是这个原因。

2401_84183802的博客 649

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

2024年大数据最全从JVM底层原理分析数值交换那些事·Java大数据高级架构师(2)

而swap(a,b)执行结束之后,该方法的堆栈会被弹出虚拟机栈,此时虚拟机栈又剩下main()方法的栈帧,由于基础数据类型的数值相当于存在局部变量中,swap(a,b)栈帧中的局部变量不会影响main()方法的栈帧中的局部变量,所以,就算你在swap(a,b)中交换了,也不会变。而两者交换之后,其实是SwapInteger(a,b)栈帧中的a里面存的地址引用变了,指向了b,但是b里面的,指向了a。原因和上面的差不多。上面的图,我们在main()方法的局部变量表中,确实看到了三个变量:args,a,b。

2401_84164503的博客 88

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

2024年大数据最新从JVM底层原理分析数值交换那些事·Java大数据高级架构师(1)

而swap(a,b)执行结束之后,该方法的堆栈会被弹出虚拟机栈,此时虚拟机栈又剩下main()方法的栈帧,由于基础数据类型的数值相当于存在局部变量中,swap(a,b)栈帧中的局部变量不会影响main()方法的栈帧中的局部变量,所以,就算你在swap(a,b)中交换了,也不会变。而两者交换之后,其实是SwapInteger(a,b)栈帧中的a里面存的地址引用变了,指向了b,但是b里面的,指向了a。原因和上面的差不多。上面的图,我们在main()方法的局部变量表中,确实看到了三个变量:args,a,b。

2401_84183726的博客 317

2024年大数据最新从JVM底层原理分析数值交换那些事·Java大数据高级架构师(2),2024年最新最详细的解释小白也能听懂

而swap(a,b)执行结束之后,该方法的堆栈会被弹出虚拟机栈,此时虚拟机栈又剩下main()方法的栈帧,由于基础数据类型的数值相当于存在局部变量中,swap(a,b)栈帧中的局部变量不会影响main()方法的栈帧中的局部变量,所以,就算你在swap(a,b)中交换了,也不会变。而两者交换之后,其实是SwapInteger(a,b)栈帧中的a里面存的地址引用变了,指向了b,但是b里面的,指向了a。原因和上面的差不多。上面的图,我们在main()方法的局部变量表中,确实看到了三个变量:args,a,b。

2401_84591685的博客 1010

Java笔记:位运算之异或交换数值原理

在学习任何语言时,都会提及到一种容易被大家忽视的运算方法–>位运算       在java中,由于JVM机制的存在,使得位运算存在感更加低,并且,为了程序的可读性,也有程序员不愿意使用位运算进行操作。       但是位运算的优秀性能,作为一个程序员是不得不学习,不管是否会用到,都应学习学习其中的原理及思想,这给我们带来的影响是潜移默化的。       基本位运算符 : & | ^ ~

Vlicet的博客 1499

Java CAS底层原理

Java CAS底层原理 Java CAS底层原理,这一篇就够了!!! CAS全称(Conmpare And Swap)比较并交换,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数 – 内存地址、预期值和新值。CAS 的实现逻辑是将内存地址的数值与预期数值想比较,若相等,则将内存位置处的值替换为新值。若不相等,则不做任何操作。 JAVA中CAS是通过自旋操作完成赋值,若值不相...

Lailai Monkey的博客 6080

(JVM)深入JAVA底层 JVM(Java 虚拟机)!带你认识JVM、程序计数器、JVM栈和方法栈还有堆内存!看看JAVA针对这些内存空间都做了什么吧!

当你想要在java中更进一步,那么钻研JVM是必不可少的!本篇将带你认识JVM中基本的内存空间,并看一看JAVA在运行时都对这些空间做了什么动作!

拔高、提升、创新! 977

CAS(比较与交换)底层原理讲解

文章目录一、什么是CAS?二、CAS底层原理三、CAS的缺点 一、什么是CAS? 二、CAS底层原理 三、CAS的缺点

mangomango123的博客 880

JVM原理之完整的一次GC流程

JVM 的 GC 是指垃圾回收,主要是对堆内存的回收。本文将介绍 JVM 中一次完整的 GC 流程是怎样的,首先抛出第一个问题,什么样的对象会是 JVM 回收的目标? 一、可达性分析算法(GC Roots) 有一种引用计数法,可以用来判断对象被引用的次数,如果引用次数为0,则代表可以被回收。这种实现方式比较简单,但对于循环引用的情况束手无策,所以 Java 采用了可达性分析算法,即判断某个对象...

天天向上 3万+
上一篇: 大N领导单独找我聊了两句:搞框架的同时别忘了算法
下一篇: 天天用SpringBoot居然还不知道它的自动装配的原理?
Javaesandyou
博客等级 码龄5年 742粉丝 563原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值