Java虚拟机---堆(Heap)与栈(Stack)上的小东西们~

 JVM(Java Virtual Machine)Java 虚拟机是整个 java 平台的基石,是 java 系统实现硬件无关与操作系统无关的关键部分,是保障用户机器免于恶意代码损害的屏障。Java开发人员不需要了解JVM是如何工作的,**但是,**了解 JVM 有助于我们更好的开(通)发(过) java(公司) 程(面)序(试)。

目录

1.堆与栈

2.方法会被堆在一起

Stack情景:3个方法,第一个方法在执行中会调用第二个方法,第二个会调用第三个。每个方法都在内容中声明了一个局部变量,而go()方法还有声明一个参数(这代表go()方法中有两个局部变量(参数处声明也算一个局部变量)) 

4.有关对象局部变量

   对象本身只会存在于堆上。栈上存放的只是对堆上对象的引用。

5.如果局部变量生存在栈上,那么实例变量呢? 

6.创建对象的过程啦~



1.堆与栈

       堆(Heap)       又称为可垃圾回收的堆(垃圾堆?啊哈)

             -------所有对象

       栈(Stack)

             -------方法调用和局部变量

2.方法会被堆在一起

      当你调用一个方法时,该方法会放在调用栈的栈顶。实际被堆上的栈的是堆栈块,它带有方法的状态,包括执行到哪一行程序以及所有的局部变量的值。    

      栈顶上的方法时目前正在执行的方法,方法会一直待在这里直至执行完毕,如果foo()方法调用bar()方法则bar()方法回放在foo()方法的上面。

放了两个方法的栈
        +++++++++++++  
栈块     + bar() s   +  《--骑上去
        +++++++++++++
        +++++++++++++     
栈块     + foo() x i +   《--局部变量和参数
        +++++++++++++
            压在下面

Stack情景:3个方法,第一个方法在执行中会调用第二个方法,第二个会调用第三个。每个方法都在内容中声明了一个局部变量,而go()方法还有声明一个参数(这代表go()方法中有两个局部变量(参数处声明也算一个局部变量)


public void doStuff(){
    boolead b = true;
    go(4);
}

public void go(int x){
    int z = x + 24'
}

public void crazy(){
    char c='a';
}

Stack的情景:

                                          crazy()    c;
                 go()  x  z;              go()     x z;     go()    x z;
doStuff()        doStuff() b;             doStuff()  b;     doStuff() b;
    1                2                         3                4

4.有关对象局部变量

       那些非primitive的变量只是保存对象的引用而已,而不是对象本身。

无论对象是否声明或创建,如果局部变量是个对该对象的引用,只有变量本身会放在栈上。

   对象本身只会存在于堆上。栈上存放的只是对堆上对象的引用。

public class StackRef{

    public void foof(){
        barf();
    }

    public void barf(){
        Duck d=new Duck();
    }
}

  不论对象在哪里声明的,它总是运行在堆上的

5.如果局部变量生存在栈上,那么实例变量呢? 

   当你创建一个对象Duck()时,Java必须在堆上帮Duck找一个位置。这会需要多少空间呢?足以存放该对象所有的实例变量的空间。

实例变量存在于对象所属的堆空间上。

情形一: Duck对象带有一个Dog对象;也就是说Duck带有Dog类型的引用变量。

问题:   shikoku需要保留对象带有的所有对象的空间?

答案:不是这样的。Java会留下空间给实例变量的值。但是引用变量的值并不是对象本身的,所有Duck对象只会留下Dog引用量而不是对象本身所用到的空间。

//情景一
public class Duck{
    private int a;
    private Dog dag;//引用并未初始  这样是在堆上不占空间的
}


//情景二
public class Duck{
    private int a;
    private Dog=new Dog();//引用并初始才会在堆上占空间
}

情景二:直到引用变量被赋值一个新的Dog对象才会在堆上占有空间。

6.创建对象的过程啦~

创建对象有三个步骤:

          1.声明:声明引用变量   Duck duck

          2.创建: 创建对象           new Duck;

          3.赋值:  连接对象与引用     Duck duck=new Duck();

                 Duck duck=new Duck();

看起来是在调用Duck()这个方法,其实并不是。

其实实在调用Duck的构造器。  

     

猜你喜欢

转载自blog.csdn.net/qq_40959340/article/details/84442369
今日推荐