JAVA对象内存管理栈和方法区解析

非堆一栈

JAVA对象内存管理 堆的解析

请打开此链接跳转到上一章:
https://blog.csdn.net/QQ1043051018/article/details/112341273

栈专门用于存放方法中的局部变量

栈空间用于存储程,序运行时在方法中声明的所有局部变量。
局部变量:就是方法中声明的变量
包括参数变量,方法体内声明的变量以及代码段大括号中声明的变量。
成员变量都存储在栈中,生命周期同方法的生命周期。

例如:回顾打饭的方法。如果在main方法中调用会发生什么?

package day05;

public class buy {
    
    
    public static void main(String[] args) {
    
    
          /*栈测试*/
        double card=10; //饭卡里有10块钱
        char lp = buy('鱼',card);
        System.out.println("card的余额: "+card); // 7
    }

    /**
     * 帮同学打饭
     * @param what  菜名
     * @param card  饭卡余额
     * @return 打到的菜名
     */
    public static char buy(char what, double card) {
    
    
        card -=3; //每次减3元
        System.out.println("余额"+card); //10
        return what;
    }
}

输出结果:
局部变量 作用范围:只限于所定义的大括号,以及这个大括号的子括号内有效。
在这里插入图片描述

局部变量的生命周期

Java程序中每调用一个方法时 , JVM在栈中为当前方法分配所需的空间,这个空间称为该方法的"栈帧”。一个栈帧专门对应一个正在调用的方法。栈帧中存储了该方法的参数、局部变量等数据变量。当方法调用完成后,方法的栈帧将被清除,局部变量同时失效。

下面我们开始模拟一下:
首先程序先执行main方法,为main方法创建2个栈帧。
在这里插入图片描述
其次在执行赋值语句
在这里插入图片描述
在继续调用方法buy
在这里插入图片描述当方法调用完成后,方法的栈帧将被清除。
在这里插入图片描述

成员变量和局部变量

成员变量和局部变量的差别如下:

局部变量:

-作用范围:只限于所定义的大括号,以及这个大括号的子括号内有效。
-储存的位置:储存在栈(zhan)内存中
-定义在方法或者语句块中;
-没有默认值,必须自行设定初始值;
-方法被调用时,存在栈中,方法调用结束,从栈中清除;
-生命周期:所属的大括号结束就消失

成员变量:

-定义在类中,方法外;
-有默认初始值,可以不显式初始化;
-所在类被实例化后,存在堆中,对象被回收时,成员变量失效;

成员变量、局部变量、静态变量的区别

在这里插入图片描述

案例 帮同学打饭:

先创建一个封装饭卡信息的类

/**
 * 封装饭卡信息的类
 */
public class Card {
    
    
    //创建2个成员变量
    String name;//饭卡的主人
    double bal; //饭卡的余额

    /**
     * 初始化所有成员变量的构造方法
     * @param name 饭卡的主人
     * @param bal  饭卡的余额
     */
    public Card(String name, double bal) {
    
    
        this.name = name;
        this.bal = bal;
    }
}

执行测试,帮同学打饭,饭卡的余额是否都减3元

public class buy {
    
    
    public static void main(String[] args) {
    
    
       /*栈测试*/
      //创建一个饭卡对象lpCard,封装饭卡的余额
      //把lpCard对象封装到Card类中
      Card lpCard=new Card("LP",10);
      //lpCard去打饭,鱼
      char lp=buy('鱼',lpCard);
      //打印饭卡的余额
        System.out.println("饭卡的余额"+lpCard.bal);
    }

    /**
     * 这个方法是 使用Card类型对象作为参数的buy方法
     * @param what
     * @param card
     * @return
     */
    public static char buy(char what,Card card){
    
    
        //从饭卡对象的bal属性中减3元
        card.bal-=3;
        //打印饭卡对象的余额属性
        System.out.println("余额: "+card.bal);
        return what; //返回打到的菜名

    }
    /**
     * 帮同学打饭
     * @param what  菜名
     * @param card  饭卡余额
     * @return 打到的菜名
     */
    public static char buy(char what, double card) {
    
    
        card -=3; //每次减3元
        System.out.println("余额"+card);
        return what; //返回打到的菜名
    }
}

在这里插入图片描述

接下来 我们用图看看运行原理:

首先程序还是执行main方法,在栈中创建栈帧
在这里插入图片描述
栈帧中包含2个局部变量 lpCard 和 lp
然后执行第一句:Card lpCard=new Card(“LP”,10);

堆中出现了一个new,就说明要在堆中创建一个Card类型对象的储存空间
而且Card中包含2个成员变量,name和bal
因为new的同时调用了有参数的构造,默认进行了初始化,所以这2个成员变量就有了初始值。

在这里插入图片描述
接下来调用buy方法,同时传递参数
调用buy方法,就要在栈中开辟栈方法的栈帧,然后保存buy的参数和局部变量
在这里插入图片描述
调用buy方法时,传递了lpCard中的地址值

在这里插入图片描述结果变成了这种格局:
card变量和lpCaed变量同时指向堆中的同一个饭卡对象。
那么此时,无论哪一方修改了饭卡对象,都是直接修改同一对象,当然就会互相影响。
在这里插入图片描述接下来,就算buy方法调用结束了,不用的这个方法帧,都不复存在了,但是栈中的对象依然存在。
因为栈中的对象只有gc能回收,至于何时回收就是没准的。况且lpCard还在调用。

在这里插入图片描述


总结:

生活案例:栈其实就像饭馆的座位一样,人来就栈上,人走就释放。

关于栈我们就只说这么多,接下来我们来看方法区

非堆—方法区

什么是方法区?

方法区用于存放类的信息。
注意是:存放类信息,不是对象信息,类是对象的模板,对象是按照类的描述,实际创建出来的东西。
对象在堆中,而类的信息是在方法区中

Java程序运行时,首先会通过类 加载器载入类文件的字节码信息(也就是.class的内容),经过解析后类的信息装入方法区。
类的信息包括成员变量和方法定义等。

在这里插入图片描述

我们以生活案例来打个比方:

其实这方法这类的信息,就好像饭馆里这个招牌菜海报,很多饭馆的墙壁上都会贴上招牌菜海报,并配上说明,然后基本厨师做这个菜的时候,都是按照墙上图片这个说明来做的,你要点菜也可以参考墙上的照片。

注意:通常方法区中的类信息 只在第一次实例化之前加载一次。不会频繁重复加载。

就好像饭馆上贴的招牌菜,一般都是一样一份。

其实在程序开始时就要调用main方法,所以首先会把Test的信息整个加载到方法区中。
然后才能照猫画虎的按照的方法区中,对Test类中的showMem()的描述一步一步的执行。
在这里插入图片描述
在执行过程中 虽然showMem()调用了2次,但是无论在任何地方调用,调用多少次。
Test中的showMem()方法的定义,只在方法区中储存一份。

这就好像现实中,墙上的招牌菜,永远只有一张,而厨师会按照这一张图片的样子和做法,反复给很多客户做多盘菜。
所以菜谱只有一份,而厨师会照着菜谱,反复执行。
在这里插入图片描述

最后方法区中类的信息的生命周期,基本上大部分类信息都只在首次使用实例化对象之前,加载一次就行了,然后一直保存在方法区中。

最后请大家时刻记住一个概览:

两室一厅:

在这里插入图片描述

最大最灵活的是堆,其次是栈,这些都是随程序运行而不断变化的,最后是方法区,方法区相对固定



以往的知识 JAVA对象内存管理 堆的解析

没学习或者想进一步了解,请打开此链接跳转到上一章:
https://blog.csdn.net/QQ1043051018/article/details/112341273

猜你喜欢

转载自blog.csdn.net/QQ1043051018/article/details/112384674
今日推荐