(转自阮一峰的网络日志,原网址http://www.ruanyifeng.com/blog/2013/11/stack.html) 
阮一峰老师终于又更新博客了,个人认为这篇文章有一定科普意义,有一定解惑点津意义,所有希望和各位分享 
学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈"。

理解这个概念,对于理解程序的运行至关重要。容易混淆的是,这个词其实有三种含义,适用于不同的场合,必须加以区分。

含义一:数据结构

stack的第一种含义是一组数据的存放方式,特点为LIFO,即后进先出(Last in, first out)。

在这种数据结构中,数据像积木那样一层层堆起来,后面加入的数据就放在最上层。使用的时候,最上层的数据第一个被用掉,这就叫做"后进先出"。

与这种结构配套的,是一些特定的方法,主要为下面这些。

  • push:在最顶层加入数据。
  • pop:返回并移除最顶层的数据。
  • top:返回最顶层数据的值,但不移除它。
  • isempty:返回一个布尔值,表示当前stack是否为空栈。

含义二:代码运行方式

stack的第二种含义是"调用栈"(call stack),表示函数或子例程像堆积木一样存放,以实现层层调用。

下面以一段Java代码为例(来源)。

class Student{ int age; String name; public Student(int Age, String Name) { this.age = Age; setName(Name); } public void setName(String Name) { this.name = Name;}}public class Main{ public static void main(String[] args) { Student s; s = new Student(23,"Jonh"); }}

上面这段代码运行的时候,首先调用main方法,里面需要生成一个Student的实例,于是又调用Student构造函数。在构造函数中,又调用到setName方法。

这三次调用像积木一样堆起来,就叫做"调用栈"。程序运行的时候,总是先完成最上层的调用,然后将它的值返回到下一层调用,直至完成整个调用栈,返回最后的结果。

含义三:内存区域

stack的第三种含义是存放数据的一种内存区域。程序运行的时候,需要内存空间存放数据。一般来说,系统会划分出两种不同的内存空间:一种叫做stack(栈),另一种叫做heap(堆)。

它们的主要区别是:stack是有结构的,每个区块按照一定次序存放,可以明确知道每个区块的大小;heap是没有结构的,数据可以任意存放。因此,stack的寻址速度要快于heap。

其他的区别还有,一般来说,每个线程分配一个stack,每个进程分配一个heap,也就是说,stack是线程独占的,heap是线程共用的。此外,stack创建的时候,大小是确定的,数据超过这个大小,就发生stack overflow错误,而heap的大小是不确定的,需要的话可以不断增加。

根据上面这些区别,数据存放的规则是:只要是局部的、占用空间确定的数据,一般都存放在stack里面,否则就放在heap里面。请看下面这段代码(来源)。

public void Method1(){ int i=4; int y=2; class1 cls1 = new class1();}

上面代码的Method1方法,共包含了三个变量:i, y 和 cls1。其中,i和y的值是整数,内存占用空间是确定的,而且是局部变量,只用在Method1区块之内,不会用于区块之外。cls1也是局部变量,但是类型为指针变量,指向一个对象的实例。指针变量占用的大小是确定的,但是对象实例以目前的信息无法确知所占用的内存空间大小。

这三个变量和一个对象实例在内存中的存放方式如下。

从上图可以看到,i、y和cls1都存放在stack,因为它们占用内存空间都是确定的,而且本身也属于局部变量。但是,cls1指向的对象实例存放在heap,因为它的大小不确定。作为一条规则可以记住,所有的对象都存放在heap。

接下来的问题是,当Method1方法运行结束,会发生什么事?

回答是整个stack被清空,i、y和cls1这三个变量消失,因为它们是局部变量,区块一旦运行结束,就没必要再存在了。而heap之中的那个对象实例继续存在,直到系统的垃圾清理机制(garbage collector)将这块内存回收。因此,一般来说,内存泄漏都发生在heap,即某些内存空间不再被使用了,却因为种种原因,没有被系统回收。

(完)

stack的三个意思的更多相关文章

  1. [转帖]Stack的三种含义

    Stack的三种含义 http://www.ruanyifeng.com/blog/2013/11/stack.html 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈&q ...

  2. Stack的三种含义

    作者: 阮一峰 日期: 2013年11月29日 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈". 理解这个概念,对于理解程序的运行至关重要.容易混淆的是,这个词 ...

  3. Stack的三种含义(数据超过栈的大小,就发生stack overflow)

    非常典型的基础知识,转自http://www.ruanyifeng.com/blog/2013/11/stack.html 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈& ...

  4. Stack的三种含义(转载--阮一峰)

    作者: 阮一峰 学习编程的时候,经常会看到stack这个词,它的中文名字叫做"栈". 理解这个概念,对于理解程序的运行至关重要.容易混淆的是,这个词其实有三种含义,适用于不同的场合 ...

  5. Stack的三种含义 ----超级经典 明白了 栈 的三种含义

    来自:http://www.ruanyifeng.com/blog/2013/11/stack.html ----------------------------------------------- ...

  6. [课程相关]附加题——stack的理解

    一.stack的三种解释 stack有三种解释,我个人理解如下. 1.用户自定义的stack 用户自定义的stack就是一般意义上的后进先出队列,从名字上就能理解了,stack由下向上增长,有一个顶指 ...

  7. 附加题-stack的理解

    这次的附加题推荐的博客是http://www.ruanyifeng.com/blog/2013/11/stack.html阮一峰的,感觉讲的深入浅出,比较适合对计算机刚刚接触的人: 下面谈谈感想: 这 ...

  8. list 删除一个元素的三种做法--python

    我们以一个字符串为元素类型的 list 为例,进行列表元素的删除: l = ['no surfing', 'flippers'] 法一:remove(val) >>> l.remov ...

  9. 【C++ STL】Stack

    1.定义 class stack<> 实作出一个stack(也成为LIFO,后进先出),你可以使用push()将任意数量的元素置入stack中,也可以使用pop()将元素依次插入次序反序从 ...

随机推荐

  1. flight学习笔记

    Flight::db()-> getOne("select 1"); 返回结果:1 Flight::db()-> getRow ("select 1, 2 f ...

  2. Redis(什么是Redis?)

    Redis是一个开源的内存数据库,可以作为缓存也可以作为消息队列.它支持的数据结构有:字符串.哈希表.列表.集合.有序集合. Redis:Redis是Remote Dictionary Server( ...

  3. div的隐藏占用空间位置关系

    display:none和visibility:hidden都是把网页上某个元素隐藏起来的功能,但两者有所区别,经过亲自实验,我发现使用 visibility:hidden属性会使对象不可见,但该对象 ...

  4. flask-login的简单实用

    # encoding: utf-8 from flask import Flask, Blueprint from flask_login import (LoginManager, login_re ...

  5. css3之弹性盒模型初探(一)

    什么是弹性盒模型? 弹性盒模型是指在父级改变大小的时候内部的自己元素也会相应的改变大小,即子集会按照父级的大小按比例自适应大小. 弹性盒模型的提出可以解决一些响应式布局的需求   如何使用弹性盒模型? ...

  6. window onload || jquery $()

    1.window 的 onload 机制只指定一个函数,且在页面DOM及静态资源加载完之后执行: window.onload = function(){ alert(); } 2.$(document ...

  7. redis 安装与php扩展

    php-redis扩展下载地址:https://pecl.php.net/package/redis/2.2.7/windows 注意:   php_igbinary-5.5-vc11-ts-x86- ...

  8. jQuery阻止向上冒泡事件

    //阻止起泡取消下面的注释 e.stopPropagation(); //或者使用这种方式 //return false; }); $('.three').click(function(e){ ale ...

  9. andriod导入v4包导致的错误

    最近升级android studio到版本3.0.1后,想要使用FragmentActivity这个类,导入v4包,发现R文件报错了,也就是找不到的意思. 如图:导包 此时选中v4包导进去. 确定之后 ...

  10. Eclipse 无法编译,提示“错误: 找不到或无法加载主类”

    jar包问题: 1.项目的Java Build Path中的Libraries中有个jar包的Source attachment指为了一个不可用的jar包, 解决办法是:将这个不可用的jar包remo ...