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.pswp.cn/news/374139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374139.shtml
英文地址,請注明出處:http://en.pswp.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…