“堆栈”:到底什么事“堆”,什么是“栈”?

是时候来看看对象和方法的生存空间了——想要了解面向对象,不知道方法和对象放在哪里是一件很尴尬的事情——毕竟我们还是要面对垃圾收集器的,想要让垃圾收集器帮你做更多的事情,我们就得一定程度上了解它的工作机制,了解方法和对象存放在哪里,否则的话,你就又要写出一个不堪一击的程序来了!

我们在前边的课程当中已经基本地提过堆的概念,没错,对象(实例)是放在堆上的——我将它形象地描述为“垃圾堆”。

被堆在栈中的方法

这个描述的标题看上去好像有点问题,但确实是形象的,方法都被放在栈当中,包括方法当中的局部变量。

这就是为什么有时候局部变量又被称作“栈变量”。

方法会被一个一个地压入栈当中,先被调用的会被压在最里边,最后被调用的则在栈顶,然后执行完毕的方法会从栈顶被弹出——我们来举个栗子:

还是熟悉的武器问题,当我们调用 reloadAndFire() 的时候,这个方法就被压入栈顶——这个时候其实栈当中也就只有它一个,它调用了 fire () 方法,那么 fire 被压入栈顶,而  reloadAndFire() 由于还没有执行完毕,就被压到了下边,然后 fire () 执行完毕了,就会被弹出栈顶, reloadAndFire() 又回到了原来的位置,那么系统就会继续执行它,然后就调用了 reload() 方法,然后又是 fire() ,最后  reloadAndFire() 执行完毕,也被弹出。

那在方法里声明的实例呢?

我们说过关于引用的内容,不论在任何地方创建实例,实例都是存在于堆上的,局部变量手里握着的只能是遥控器。

实例里的变量

说到实例,它里边的变量是跟着实例一起住在堆上的,他们的生存周期就要比局部变量长了很多——随着实例生死。所以,我们在方法当中调用实例的变量,但方法被弹出实例变量也不会就此消失,而是等到实例被回收的时候才会跟着实例魂归田鸡。

创建一个对象

这个时候我们就能详细的描述创建一个对象的全过程了:

  1. 声明了储存器,把它标记为某个实例的引用类型;
  2. 创建一个对象,它存在于堆
  3. 将堆上的对象与储存器中的引用连接起来——给引用里传入对象的地址。

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.