方法执行过程jvm的内存分配

方法执行过程jvm的内存分配

方法在执行过程当中,JVM中的内存是如何分配的呢,内存是如何变化的?

1、方法只定义,不调用,是不会执行的,并且在JVM中也不会给该方法分配"运行所属”的内存空间。

只有在调用这个方法的时候,才会动态的给这个方法分配所属的内存空间.

2、在JVM内存划分工上有这样三块主要的内存空间 (当然除了这三块之外还有其它的内存空间)

方法区内存

堆内存

栈内存

3、关于栈数据结构

栈:stack,是一种数据结构

数据结构反应的是数据的存储形态.

数据结构是独立的学科,不属于任何编程语言的范畴,只不过在大多数编程语言当中要使用数据结构。作为程序员需要提前精通:数据结构+算法 [计算机专业必修一门课程]

java程序员在不精通数据结构和算法的前提下,也可能进行java开发,因为java有一套 庞大的类库支撑,.别人写好了,直接用。[ JavasE当中的集合章节使用了大量的数据结构]

常见的数据结构: 数组 ,队列 ,链表 ,二叉树 ,哈希表/散列表 ……

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WzMFc82j-1593790792814)(D:\Typora图片\1593275996037.png)]

4、方法代码片段存在哪里?方法执行的时候执行过程的内存在哪里分配?

方法代码片段属于. class字节码文件的一部分,字节码文件在类加载的时候,将其放到了方法区当中。所以JVM中的三块主要的内存空间中方法区内存最先有数据。存放了代码片段。

代码片段虽然在方法区内存当中只有一份,但是可以被重复调用

每一次调用这个方法的时候,需要给该方法分配独立的活动场所,在栈内存中分配。

栈内存中分配。(栈内存中分配方法运行的所属丙存空间)

5、方法在调用的瞬间,会给该方法分配内存空间,会在栈中发生压栈动作,方法执行结束之后,给该方法分配的内存空间全部释放,此时发生弹栈动作.

压栈:给方法分配内存

弹栈:释放该方法的内存空间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B8zgnk8X-1593790792825)(D:\Typora图片\1593276796103.png)]

一执行就在执行时候会先执行上面一个主方法然后再执行m方法

只要方法一开始执行(比如这里的主方法一执行就会在栈内存里面分配空间,然后再为m方法分配空间,也就是造成了压栈

main方法最先调用肯定是在栈底部,第二个调用m方法,所以m方法会压住main方法,所以m方法在执行过程当中main方法是暂停

【m方法执行到m();不能继续往下走,是等着m执行结束之后,m();才算结束,然后main方法才能继续往下执行】

只要调方法就造成压栈,方法执行结束后内存空间全部释放,这是弹栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MJXoctxZ-1593790792830)(D:\Typora图片\1593277011706.png)]

m方法执行到m();不能继续往下走,是等着m执行结束之后,m();才算结束,然后main方法才能继续往下执行所以i是局部变量类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qCBF61Ue-1593790792836)(D:\Typora图片\1593277941850.png)]

最后调用的方法一定最先结束(是栈数据结构的特点)

这就是栈数据结构

分析以下程序的输出结果

public class yu{
    public static void main(String[] args){
        System.out.println("main begin");
        m1();//只有当这行结束下面的才会执行
             //暂停
        System.out.println("main over");
    }
    public static void m1(){
      System.out.println("m1 begin");
      m2();  //暂停
      System.out.println("m1 over"); 
    }
     public static void m2(){
      System.out.println("m2 begin");
      m3();  //暂停
      System.out.println("m2 over"); 
    }
     public static void m3(){
      System.out.println("m3 begin");
      System.out.println("m3 over"); 
    }
}

首先从程序入口开始执行
    main begin
    main begin执行完毕就到了 m1();只有 m1();执行结束下面的main over
    所以先执行m1也就是去调用m1
    m1 begin
    同理m1执行完毕也才能执行m1 begin所以先执行m2也就是去调用m2
    m2 begin
    同理调用m3
    m3 begin
    m3 over
      m3 over结束就代表m3由暂停恢复了活跃状态,所以也就执行m2 over
    m2 over输出后m2就结束了
    m2结束就输出m1 over
    m1 over输出又表示m1结束,结束就输出main over
    
    
    所以执行顺序
     main begin
     m1 begin
     m2 begin
     m3 begin
     m3 over
     m2 over
     m1 over
     main over

画出内存分配图

public class yu{
    public static void main(String[] args){
       int a=10;
       int b=20;
       int retValue=sumInt(a,b);//调用非法,因为在同一个类当中所以省略了类名.
        System.out.println("retValue="+retValue);
      
    }
    public static int sumInt(int i,int j){
        int result=i+j;
        int num=3;
        int retValue=divide(result,num);
        return retValue;
     
    }
     public static int divide(int x,int y){
      int z=x/y;
      return z;
    }
     
}
运行结果10

首先要执行main方法就要把yu这个类加载到虚拟机当中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jWnIAjO6-1593790792840)(D:\Typora图片\1593302555830.png)]

程序往下走回去调用main方法,main方法里面有String,然后一直到main方法的输出

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZQq0DdlF-1593790792842)(D:\Typora图片\1593302615331.png)]

怎样判断是不是字节码(标识符)文件

看颜色或者找lang

(如果是sum公司写的在EditPlus中是会显示红色,但是如果是自己写的那就没有显示颜色)

EditPlus中,字体颜色为红色的表示一个类的名字,并且这个类是JavaSE类库中自带的,其实JavaSE类库中自带的类,比如String.classSystem.class 这些类的名也是标识符,只要是类名就一定是标识符

查看其他标识符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YRSH30k4-1593790792844)(D:\Typora图片\1593302995307.png)]

在lib中找到rt.jar

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bmLMuOYS-1593790792847)(D:\Typora图片\1593303025382.png)]

并打开

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DM0lryK-1593790792849)(D:\Typora图片\1593303072770.png)]

点击java中的lang

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WzvQpA1D-1593790792852)(D:\Typora图片\1593303106592.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D86SwGbt-1593790792854)(D:\Typora图片\1593303121025.png)]

点击lang以后看见的全是字节码文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amMbCOGb-1593790792855)(D:\Typora图片\1593305472255.png)]

注意:方法区内存是最先开始执行的

加载完毕也就开始从程序入口处开始执行,

然后执行栈内存:

开始执行main方法,main方法所属的内存空间在栈内存中分配

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ukD6IX2S-1593790792857)(D:\Typora图片\1593308437299.png)]

public class yu{
    public static void main(String[] args){
       int a=10;
       int b=20;
       int retValue=sumInt(a,b);    //程序运行到这里
        System.out.println("retValue="+retValue);
      
    }
    public static int sumInt(int i,int j){
//把a里面的10传递给i b里面20传递给j
       int result=i+j;//是cpu进行计算
        int num=3;
        int retValue=divide(result,num);
        return retValue;
     
    }  

执行到了 int retValue=sumInt(a,b);等号右边先执行,当右边方法没有结束的时候,等号左边永远执行不了

所以会先去调用sumInt方法,调用执行就会为它分配内存空间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1NgT5yIa-1593790792859)(D:\Typora图片\1593304857278.png)]

sumInt里面有两个局部变量ij

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DziGX3AE-1593790792861)(D:\Typora图片\1593308639159.png)]

ij里面保存的是什么东西就看 int retValue=sumInt(a,b);这里传递过来的是什么

i j里面保存什么= a b传递什么

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d2J9ShPU-1593790792863)(D:\Typora图片\1593309242103.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fNUw8ZHB-1593790792866)(D:\Typora图片\1593309475648.png)]

方法调用的时候,在参数传递的时候,实际上传递的是变量中保存的那个值传过去了

此时main方法处于暂停状态,从图中也可以看出它被sumInt压栈了,此时活跃的是sumInt方法,会由CPU进行计算i+j=30

public class yu{
    public static void main(String[] args){
       int a=10;
       int b=20;
       int retValue=sumInt(a,b);
        System.out.println("retValue="+retValue);
      
    }
    public static int sumInt(int i,int j){
//把a里面的10传递给i b里面20传递给j
       int result=i+j;//是cpu进行计算
        int num=3;
        int retValue=divide(result,num);
        return retValue;
     
    }  

所以会有一个为30的result,注意这是一个局部变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KvZwPJBo-1593790792867)(D:\Typora图片\1593310208440.png)]

接着执行int num=3;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZEONOH1j-1593790792869)(D:\Typora图片\1593311338585.png)]

执行下一行int retValue=divide(result,num);

此时divide执行时sumInt处于暂停状态

它会去调用divide方法,又会发生压栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hyVhZGr1-1593790792870)(D:\Typora图片\1593311761654.png)]

public class yu{
    public static void main(String[] args){
       int a=10;
       int b=20;
       int retValue=sumInt(a,b);
        System.out.println("retValue="+retValue);
      
    }
    public static int sumInt(int i,int j){
        int result=i+j;
        int num=3;
        int retValue=divide(result,num);
        return retValue;
     
    }
     public static int divide(int x,int y){
      int z=x/y;
      return z;
    }
     
}
运行结果10

执行divide方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BwHvNU2D-1593790792872)(D:\Typora图片\1593311805930.png)]

执行 int z=x/y;同样还是CPU进行计算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DeTWxqLl-1593790792873)(D:\Typora图片\1593311892087.png)]

然后执行返回语句

return z;

public class yu{
    public static void main(String[] args){
       int a=10;
       int b=20;
       int retValue=sumInt(a,b);
        System.out.println("retValue="+retValue);
      
    }
    public static int sumInt(int i,int j){
        int result=i+j;
        int num=3;
        int retValue=divide(result,num);//执行结束
        //执行结束会把值给retValue
        return retValue;
     
    }
     public static int divide(int x,int y){
      int z=x/y;
      return z; //执行返回语句return z;
    }           //return z;代表 int retValue=divide(result,num);执行结束
     
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wpYSDZTE-1593790792876)(D:\Typora图片\1593312710212.png)]

继续往下return

public class yu{
    public static void main(String[] args){
       int a=10;
       int b=20;
       int retValue=sumInt(a,b);//sumInt执行结束赋值给 retValue
        System.out.println("retValue="+retValue);
      
    }
    public static int sumInt(int i,int j){
        int result=i+j;
        int num=3;
        int retValue=divide(result,num);//执行结束
        //执行结束会把值给retValue
        return retValue;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GGeEJyzL-1593790792877)(D:\Typora图片\1593313607434.png)]

可以看出栈内存里面保存的是局部变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0UihsJ6A-1593790792879)(D:\Typora图片\1593313687930.png)]

画图依据

1、只要涉及到参数传递的问题,传递的是变量中保存的值

2、画图的时候,必须遵循方法自上而下的顺序依次执行的原则

画出程序的输出结果

public class zhang{
    public static void main(String[] args){
       int i=10;
       method(i);         //先去调用method方法然后输出method里面的i为11
                         //输出11以后表示method执行完毕,执行完毕就再去执行"main="+i的结果
        System.out.println("main="+i);//输出10  输出的是类体中的i
                       //这里  System.out.println("main="+i);的i输出的是 int i=10;这里的i
    }
    public static void method(int i){
        i++;
        System.out.println("method"+i);//输出11
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值