• 方法的参数传递机制


    最近看到一道题目,尝试分析一下

    public class TestBuMa {
        public static void main(String[] args){
            int i=1;
            String str="Hi";
            Integer num=2;
            int[] arr={1,2,3,4};
            MyData myData=new MyData();
    
            change(i,str,num,arr,myData);
            System.out.println("i="+i);
            System.out.println("str="+str);
            System.out.println("num="+num);
            System.out.println("arr="+ Arrays.toString(arr));
            System.out.println("myData.a="+myData.a);
        }
        public static  void  change(int j,String s,Integer n,int[] arr,MyData myData){
            j+=1;
            s+=",张三";
            n+=1;
            arr[0]+=1;
            myData.a+=1;
        }
    }
    class MyData{
        int a =10; 
    }

    jvm内存区域

    image

    根据java虚拟机内存区域,可以将上面数据类型存储区域进行划分

    Java Heap 是 Java 虚拟机所管理的内存中最大的一块,它是所有线程共享的一块内存区域。几乎所有的对象实例,成员变量和数组都在这类分配内存。Java Heap 是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”。根据 Java 虚拟机规范的规定,Java 堆可以处在物理上不连续的内存空间中,只要逻辑上是连续的即可。如果在堆中没有内存可分配时,并且堆也无法扩展时,将会抛出 OutOfMemoryError 异常。

    方法区也是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区域又被称为“永久代”。

    栈,方法里的局部变量存在栈中,栈中有一个局部变量表用来存放方法参数和方法内部的局部变量,其存放的数据类型是编译器可知的基本数据类型,对象引用。局部变量表所属要的内存在编译阶段就会分配完成。

    下面用图示展示main方法里的局部变量在jvm内存中的位置

    image

    image

    虚拟机栈描述的是 Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,栈它是用于支持续虚拟机进行方法调用和方法执行的数据结构。

    执行change方法之后再看各变量的值。

     

    image

    执行完change之后当前私有区域的栈内存就会被回收因此最后执行结果是

    1,Hi,2,[2,2,3,4],11

    形参是基本数据类型则传递数据值

    形参是引用数据类型传递的是地址值(注:String常量,包装类的对象不可变性)

  • 相关阅读:
    程序员转型架构师,推荐你读这几本书
    Dubbo服务发现源码解析
    高可用架构之限流降级
    为什么Kafka速度那么快
    从分布式一致性到共识机制(三)拜占庭问题
    从分布式一致性到共识机制(二)Raft算法
    三分钟看完京东区块链白皮书
    轻松理解零知识证明
    三大去中心化交易协议对比
    从分布式一致性到共识机制(一)Paxos算法
  • 原文地址:https://www.cnblogs.com/gyjx2016/p/12582477.html
Copyright © 2020-2023  润新知