Stack的三种含义

作者:阮一峰

学习编程的时候,经常会看到stack这个词,它的中文名字叫做”栈”。

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

含义一:数据结构

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

图1

 

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

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

  • 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方法。

图2

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

含义三:内存区域

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

图3

它们的主要区别是: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也是局部变量,但是类型为指针变量,指向一个对象的实例。指针变量占用的大小是确定的,但是对象实例以目前的信息无法确知所占用的内存空间大小。

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

图4

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

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

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

(完)

源自阮一峰个人博客

转载于:https://www.cnblogs.com/wangzhigang/p/4974910.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374139.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NXP UWB NCJ29D5开发(二)BlinkyLed例程

路径为UWB\NCJ29D5\NCJ29D5_CAS_Examples_v1.4\onic\BlinkyLed\toolsupport\keil 例程怎么来的可以看看上一篇NXP UWB NCJ29D5开发(一)环境搭建 1、 //系统选择外部晶振,时钟频率为55.2Mhz phscaAppHal_Init(PHSCA_APPHAL_XO_CLOCK_SOURCE_…

你要看透的56条人生哲理

当你踌躇不前、站在人生十字路口时候,这56条哲理或许能助你一臂之力!      1.拿得起,放得下      我们每个人都有很多“宝贝”,但你不可能什么都得到,在某些时候一定要学会拿得起,放得下…

使用Spring和Java泛型简化数据访问层

1.概述 本文将着重于通过对系统中的所有实体使用单个通用的数据访问对象来简化DAO层 ,这将导致优雅的数据访问 ,而不会造成不必要的混乱或冗长。 2. Hibernate和JPA DAO 大多数生产代码库都有某种DAO层。 通常,实现范围从没有抽象基类的多个…

强肝保肝养肝4大食物

“强肝的食物,保肝的食物有哪些,养肝的食物有哪些”如果您对这些食物不了解不明白。那就看看专家为您推荐的四款强肝保肝养肝的食物。荔枝(供图/华盖)一、是荔枝,荔枝可以保肝,对肝有好处根据《本草纲目》记载荔枝有强肝健胰的效果…

如何查看注解实现_该怎么运用注解呢?Java团队元老有话说

来源 | 异步 15讲能学好诞生24年的JAVA吗?你当然会感到怀疑,众所周知,在技术向的IT论坛上,“如何在十天之内快速掌握好Java?”这类问题,往往会招来嘲笑。来源于知乎但在当下,5分钟能看完一部电影…

NXP S32K144开发(一)环境搭建和新建工程

1、首先需要安装S32 Design Studio for ARM,在NXP官网可以搜索到,这玩意也是基于eclipse的 安装好后就可以打开了。 2、新建工程 过程可以参考NXP官网: https://www.nxp.com/document/guide/get-started-with-the-s32k144evb:NGS-S32K144E…

首先记录异常的根本原因

Logback日志库的0.9.30版本带来了一个很棒的新功能:从根(最内部)异常而不是最外部异常开始记录堆栈跟踪。 当然,我的兴奋与我贡献了此功能无关。 用塞西尔德米勒(Cecil B. de Mille) 的话来解释&#xff1a…

成功醒言

成功醒言 C01 只有敢犯错误的人才能成事; 只有不犯同样错误的人才能成大事。 C02 固执≠执著; 幻想≠希望。 固执是无目标的执著; 执著是有目标的固执。 幻想是无法兑现的希望; 希望是有望实现的幻想。 固执地执著幻想&#xf…

Android 中的 Service 全面总结

1、Service的种类 按运行地点分类: 类别区别 优点缺点 应用本地服务(Local)该服务依附在主进程上, 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不…

python基础学习1-三元表达式和lambda表达式

#!/usr/bin/env python # -*- coding:utf-8 -*- 三元运算 if else 的简写name "alex" if 11 else "SB" #如果条件成立 赋alex 否则 赋SB print(name)#--------------lambda表达式 f2 lambda a1,a2:a1a2100 #等价 下边函数定义 def f1(a1,a2): return …

怎么让存储过程通用化_怎么做分布式存储的面试?

cholerae 大神已经做了详细回答,http://zenlife.tk/interview-for-distributed-storage.md写于几年前,内容有点稚嫩,WAL辨识度很高, 其他问题一般.CAP不会再问了,专业的存储文献中很少(几乎不)提及CAP或PACELC, 这个词用于市场和销…

Java EE中的配置管理

我尝试配置管理在云计算中具有很多相关性 争论 较早。 实际上,我大胆地宣称配置管理是任何认真尝试从软件中节省几美元的基石。 那么什么是配置管理及其主要目标? 在不使事情变得过于复杂的情况下,我认为接下来的两个目标与事实相差不远。 以…

十年总结,一个JAVA人的十年人生路

十年总结-开篇:歇一歇,才能走的更远经常见坛子里有人问,学习java该如何入手,或者是该学java还是学XX语言。我一直觉得,编程跟语言关系不大,重点是要有解决问题的思路。学习一门语言,其实只是寻求…

(四)Qt实现自定义模型基于QAbstractTableModel (一般)

Qt实现自定义模型基于QAbstractTableModel 两个例子 例子1代码 Main.cpp #include <QtGui>#include "currencymodel.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);//数据源QMap<QString, double> currencyMap;currencyMap.insert(…

pt-query-digest使用介绍【转】

本文来自&#xff1a;http://isadba.com/?p651 一、pt-query-digest参数介绍. pt-query-digest --useranemometer --passwordanemometerpass --review h192.168.11.28,Dslow_query_log,tglobal_query_review \--history h192.168.11.28,Dslow_query_log,tglobal_query_re…

python代码模板_python 代码模板

python中的Module是比较重要的概念。常见的情况是&#xff0c;事先写好一个.py文 件&#xff0c;在另一个文件中需要import时&#xff0c;将事先写好的.py文件拷贝 到当前目录&#xff0c;或者是在sys.path中增加事先写好的.py文件所在的目录&#xff0c;然后import。这样的做法…

Java并发教程–重入锁

Java的synced关键字是一个很棒的工具–它使我们能够以一种简单可靠的方式来同步对关键部分的访问&#xff0c;而且也不难理解。 但是有时我们需要对同步进行更多控制。 我们要么需要分别控制访问类型&#xff08;读取和写入&#xff09;&#xff0c;要么使用起来很麻烦&#xf…

找出互联网类似以下图的实例

转载于:https://www.cnblogs.com/sghcjy/p/4978851.html

python比较运算符重载_python运算符重载

1、打印操作会首先尝试__str__和str内置函数&#xff0c;他通常返回一个用户友好显示。__repr__用于所有其他环境&#xff0c;用于交互式模式下提示回应以及repr函数&#xff0c;如果没有使用__str__&#xff0c;则会使用print和str。它通常返回一个编码字符串&#xff0c;可以…

使用Spring MVC开发Restful Web服务

REST简介 摘自Wikipedia&#xff1a; REST风格的体系结构由客户端和服务器组成。 客户端向服务器发起请求&#xff1b; 服务器处理请求并返回适当的响应。 请求和响应围绕资源表示的传递而构建。 资源本质上可以是可以解决的任何连贯且有意义的概念。 正如您所阅读的&#xff0…