Stack的三种含义

学习编程的时候,经常会看到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,即某些内存空间不再被使用了,却因为种种原因,没有被系统回收。

时间: 2024-12-22 10:29:59

Stack的三种含义的相关文章

Mysql 5.7.19三种安装方式手册

Mysql 5.7.19三种安装方式手册 ** 环境准备 操作系统:CentOS 软件:MySQL-5.7.19 ** ** 一.RPM 方式安装 进入官方网站:https://www.mysql.com 注册账号 downloads 选择MySQL Community Edition (GPL)>>Community (GPL) Downloads >>MySQL Community Server (GPL)>>download 操作系统:Red Hat Enterp

从三种算法简要分析外链的重要性

福清SEO对于搜索引擎算法从没有深入研究过,也不提倡去深入研究.笔者认为一般的企业SEOer只需要对算法有所了解,浅尝辄止就可以了. 下文福清SEO列举三种著名搜索引擎算法进行初入门分析,不为别的,就是为证明外链对于网站排名的重要性提供理论依据,希望对大家有帮助. 关于Hits算法 Hits算法是在1997年由康奈尔大学博士提出的,是针对一个页面重要性分析的算法.Hits算法有两个概念,分别是枢纽值与权威值. 枢纽值的含义就是该页面所有导出链接的权值和. 比如:福清SEO博客导出链接20个,这2

三种中文分词算法优劣比较

到目前为止,中文分词包括三种方法:1)基于字符串匹配的分词:2)基于理解的分词:3)基于统计的分词.到目前为止,还无法证明哪一种方法更准确,每种方法都有自己的利弊,有强项也有致命弱点,简单的对比见下表所示: 各种分词方法的优劣对比 分词方法 基于字符串匹配分词 基于理解的分词 基于统计的分词 歧义识别 差 强 强 新词识别 差 强 强 需要词典 需要 不需要 不需要 需要语料库 否 否 是 需要规则库 否 是 否 算法复杂性 容易 很难 一般 技术成熟度 成熟 不成熟 成熟 实施难度 容易 很难

php实现快速排序的三种方法

这篇文章主要介绍了php实现快速排序的三种方法,三种方法各有优缺点,需要的朋友可以参考下 写了三种php快速排示例,第一种效率低但最简单最容易理解,第二个是算法导论上提供的单向一次遍历找中值方法,第三种是双向遍历找中值经典快排算法.三组算法实现和比较如下:   方法一:该方法比较直观,但损失了大量的空间为代价,使用了效率较低的merge函数.在三种方法中效率最低.最坏情况下算法退化为(O(n*n))  代码如下: function quick_sort($array) {  if(count($

三种对象传参和ModelDriven的原理

三种对象传参和ModelDriven的原理 ModelDriven的作用 所谓ModelDriven,意思是直接把实体类当成页面数据的收集对象.比如,有实体类User如下: package cn.com.leadfar.struts2.actions;   publicclass User {     privateintid;     private String username;     private String password;     privateintage;     pri

大数据流式计算三种框架:Storm,Spark和Samza

许多分布式计算系统都可以实时或接近实时地处理大数据流.本文将对三种Apache框架分别进行简单介绍,然后尝试快速.高度概述其异同. Apache Storm 在Storm中,先要设计一个用于实时计算的图状结构,我们称之为拓扑(topology).这个拓扑将会被提交给集群,由集群中的主控节点(master node)分发代码,将任务分配给工作节点(worker node)执行.一个拓扑中包括spout和bolt两种角色,其中spout发送消息,负责将数据流以tuple元组的形式发送出去:而bolt

操作系统-关于进程间的三种状态的转移 能不能结合具体的程序实例说明一下

问题描述 关于进程间的三种状态的转移 能不能结合具体的程序实例说明一下 running stateready statewaiting state这三种不同的状态之间的相互转换,能不能结合具体的程序实例说明一下 比如编译器等等 解决方案 运行.阻塞.就绪 是进程的3种基本状态,有些划分成更细的则分成4个状态(运行.就绪.睡眠.阻塞)就以楼主分的这3种基本状态来解释:运行态:进程正在执行时的状态阻塞态:进程由于需要进行的IO操作,不得不等待其他进程IO或者某个IO事件完成,此时进入阻塞等待状态就绪

大数据处理的三种框架:Storm,Spark和Samza

许多分布式计算系统都可以实时或接近实时地处理大数据流.下面对三种Apache框架分别进行简单介绍,然后尝试快速.高度概述其异同. Apache Storm 在Storm中,先要设计一个用于实时计算的图状结构,我们称之为拓扑(topology).这个拓扑将会被提交给集群,由集群中的主控节点(master node)分发代码,将任务分配给工作节点(worker node)执行.一个拓扑中包括spout和bolt两种角色,其中spout发送消息,负责将数据流以tuple元组的形式发送出去:而bolt则

《 Java并发编程从入门到精通》 常见的内存溢出的三种情况

作者:张振华    购买链接:天猫商城  JD商城  当当书店 鸟欲高飞先振翅,人求上进先读书.本文是原书的第9章 线程的监控及其日常工作中如何分析里的9.3.3节常见的内存溢出的三种情况. 3. 常见的内存溢出的三种情况: 1)JVM Heap(堆)溢出:java.lang.OutOfMemoryError: Java heap space JVM在启动的时候会自动设置JVM Heap的值, 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置.Heap的大小是Young Gene