谈谈Java构造器与垃圾收集器(1)

浅谈Java构造器与垃圾收集器

目录

浅谈Java构造器与垃圾收集器

栈与堆

方法会被堆在一起

栈上的对象引用

 

栈与堆

在我们能够弄清楚java创建对象的真正发生过程之前,我们需要退回一步,先对生存在java中的事务更加了解,这也就表示我们要对栈与堆有着更多的认识。

  • 在java中,我们会更加注重内存中的两种区域,一个是对象的生存空间堆(heap),一个是方法调用及变量的生成空间栈(stack)。当java虚拟机启动时,它会从底层的操作系统中取得一块内存,并以此区域来执行java程序。而且我们要知道,所有的对象都存活与可垃圾回收的堆上。但是我们却没有绝对的定义过变量存货的区域。那是因为变量分为(实例变量和局部变量),实例变量存在于所属的对象中,也就是说它存活于堆上,而局部变量的和方法的参数都是声明在方法中,是暂时的,所以他们生命周期只限于这个方法的执行时间,所以这种区域变量,又被称为栈变量,所以它存活于栈中
  • 用一张图来说明就是如下所示:

谈谈Java构造器与垃圾收集器(1)

方法会被堆在一起

当我们调用一个方法的时候,这个方法会被放在调用栈的栈顶,如果这个方法继续调用别的方法的话,那么被调用的新的方法就会被放在这个栈的栈顶,压着刚才那个方法,也就形成了一个栈块,而栈块的执行顺序就是由上到下

  • 这里我们用代码举一个简单的例子:有一个stack类他又三个方法,第一个方法在执行过程中会调用第二个方法,第二个方法会调用第三个方法。每个方法都在内容中声明一个局部变量,而go()还会声明一个参数(这里代表go方法有两个局部变量)。
  • 代码块内容如下:
    public void doSuff(){
        boolean b=true;
        go(4);
    }
    
    public void go(int x){
        int z=x+24;
        crazy();    
    }
    
    public void crazy(){
        char c='a';
    }

     

  • 那这个方法在栈中的执行过程是怎样的呢?如图:谈谈Java构造器与垃圾收集器(1)

栈上的对象引用

我们要明白,非primitive的变量,它只是保存对象的引用而已,而不是对象本身。所以我们知道了对象的存活空间--堆,却对引用该对象的局部变量或者实例变量存在的空间有所疑虑。所以我们接着介绍如果一个类里面的实例变量,是引用别的对象的引用对象,和一个类里面的某一个方法的局部变量,是引用别的对象的引用对象,它们两种类型的存活空间又是如何?

  • 不论对象是在哪里声明的,对象本身只会存在于堆上。
  • 对象引用于primitive注数据类型变量都是放在栈上。
  • 不懂?来一波代码和图,还不懂的话,你砍我!
public class StackRef{
    public void foof(){
        barf();
    }
    public void barf(){
        Duck d=new Duck(24);
    }
}
  • 上图:
  • 谈谈Java构造器与垃圾收集器(1)

以上就是局部变量生存空间的说明--生存在栈上,那么实例变量呢?

  • 如果我们创建一个对象,那么我们需要的内存空间又是多少呢?泛泛的说,这个空间是不是最起码能存下类里面的实例变量?是不是发现了端倪?没错,实例变量就是存在于对象所属的堆空间上
  • 记住对象的实例变量的值,是存在对象中。如果实例变量都是primitive主数据类型的,则java会根据类型大小分配空间,int需要32,但不论int的值多大,它都是32位。所以java并不在乎类型的值,只在乎类型。
  • 举个例子:现在有一个类,里面有一个实例变量,实例变量的类型是另一个类的类型,那么我们分析一下它们在堆上的联系。
public class CellPhone(){
    private Antenna ant;   //声明引用对象,没有赋值
    priavte Antenna antt=new Antenna();  //声明并赋值
}
  • 上图:
  • 谈谈Java构造器与垃圾收集器(1)

以上就是对栈和堆的生动理解,接着会从创建对象,构造函数方面入手,更加深入的理解java的构造器与垃圾收集器何时会对对象下手?销毁它?

 

感谢浏览,希望对你有所帮助。