JVM筆記四-棧區

2020-12-23 凱哥Java

JVM學習筆記之棧區

本文主要內容:

棧是什麼?棧幀又是什麼?在JVM中,main方法調用say方法後,是怎麼運行的?本文將詳細講解棧。希望大家學了之後,對棧有更深的了解。

心法:在JVM中,棧管運行,堆管存儲。

棧數據結構特點:先進後出。生活中常見的case就是彈夾。最後一個壓進彈夾的子彈,最先出彈夾。

Stack棧:棧也叫棧內存,主管Java程序的運行,是在線程創建時創建,它的生命周期跟隨線程的生命周期,線程結束,棧內存也就被釋放了。對於棧來說,不存在垃圾回收問題,只要是線程一結束,該棧就over了。生命周期和線程一直的,是線程私有的。

8中基本類型的變量+對象的引用變量+實例方法都是在函數的內存中分配的。

棧中存儲的是什麼?

在了解棧之前,先來了解另一個概念:棧幀。

棧幀

棧幀(Stack Frame):用於支持虛擬機進行方法調用和方法執行的數據結構。它是虛擬機運行時數據區中的虛擬機棧的棧元素。

棧幀存儲了方法的局部變量表、操作數棧、動態連接和方法返回地址等信息。每個方法從調用開始至執行完成的過程,都對應這一個棧幀在虛擬機棧裡面從入棧到出棧的過程。

額,什麼叭叭叭的,說的什麼意思呢?簡單如下:

棧幀中主要保存3類數據:

本地變量(Local variables):輸入參數和輸出參數以及方法內的變量;

如上圖中的 int x,int y就是輸入參數

Int result就是輸出參數。

其中的X、Y、result都是方法內的變量

棧操作(Operand Stack):記錄出棧、入棧的操作;

棧幀數據(fram Date):包括類文件、方法等等。

棧運行的原理:

棧中的數據都是以棧幀的格式存在,棧幀是一個內存區塊,是一個數據集,是一個有關方法(Method)和運行期,數據的數據集。

當一個方法A被調用的時候,就產生了一個棧幀F1,並被壓到棧中;

A方法調用了B方法,於是產生了棧幀F2也被壓入棧中;

B方法又調用了C方法,於是產生棧幀F3,也被壓入到棧中;

依次類推。

當執行完畢後,先彈出F3棧幀,在彈出F2棧幀,在彈出F1棧幀。依次類推。

遵循」先進後出/後進先出」的原則。

代碼演示:

寫個main函數,在main方法中,調用say方法。然後查看輸出結果。

運行結果:

當程序運行到3行的時候,調用了主線程main函數,這個時候產生了棧幀F1,被壓入棧,代碼繼續向下走;

當代碼執行到第5行的時候,調用了say方法,這個時候產生了棧幀F2,發現後面還有代碼需要執行,F2就被壓入棧;

當執行第10行的時候,say方法調用了showCode方法,這個時候就產生了F3。進入方法showCode方法後,後面還有代碼,F3壓棧,繼續執行。

當執行到第17行的時候,發現沒有需要執行的了。F3就從棧裡面被彈出棧了;

接著回到say方法裡面,繼續執行,程序走到第12行的時候,發現say方法執行完成了,於是F2就被彈出棧了;

程序回到main方法中,也就是該執行第6行了,執行完第6行,當到底7行的時候,發現主函數也執行了了,於是F1就被彈出棧了;

整個線程執行完成,棧區被清空。程序結束。如下圖:

一個線程中的方法調用鏈可能會很長,很多方法都同時處於執行狀態。對於執行引擎來說,在活動線程中(爭搶到CPU執行權的),只有位於棧頂的棧幀才是有效的,成為當前棧幀(Current Stack Frame),與這個棧幀相關聯的方法稱為當前方法(Current Method)。執行引擎運行的所有字節碼指令都是只針對於當前棧幀進行操作的。

棧幀概念模型如下圖:

需要說明的是:每個方法執行的同時都會創建一個棧幀,用於存放局部變量表、操作數棧、動態連接、方法返回等等數據。每個方法從被調用至執行完成的過程,就對應著一個棧幀在虛擬機中入棧和出棧的過程。棧的大小和具體JVM的實現有關,通常在256K~756K之間,約等於1Mb左右。

棧+堆+方法區的交互關係

HotSpot是使用指針的方法來訪問對象的:

Java堆中會存放訪問類元數據的地址,reference存放的就直接是對象的地址。

相關焦點

  • 程式設計師每日一題-jvm裡方法和方法區、棧區的二三事
    JAVA虛擬機運行時數據區的邏輯圖好,對照上圖,逐項解釋A:堆區是JVM 所管理的內存中最大的一塊。線程共享,主要是存放對象實例和數組。堆區是jvm裡面最需要深入研究的一塊區域,這裡面涉及內存分配,區域劃分,對象信息,垃圾回收。可以說如果java程式設計師對堆區不熟悉,那麼一定寫不出好的代碼。本文暫時不深入討論,後續會開專題深入講解。B:棧區,也叫虛擬機棧,顧名思義,它是一個棧,先進後出。它是線程創建時跟著創建,生命周期和線程一致,是線程私有的。
  • JVM超神之路:年後跳槽需要的JVM知識點,周末給你整理了一份!!!
    13、棧上分配是什麼意思14、簡述下對象的分配規則四、實戰調優1、你在項目中都使用了哪些參數列印GC?2、常用的調優工具有哪些?JDK內置的命令行:jps(查看jvm進程信息)、jstat(監視jvm運行狀態的,比如gc情況、jvm內存情況、類加載情況等)、jinfo(查看jvm參數的,也可動態調整)、jmap(生成dump文件的,在dump的時候會影響線上服務)、jhat(分析dump的,但是一般都將dump導出放到mat上分析)、jstack(查看線程的)。
  • jvm面試系列一:java內存模型你掌握了多少?
    說明:因為知識點較多,擴展開來篇幅太長,jvm系列面試題將會分解開來從內存模型,垃圾回收,類加載機制,參數調優等多個角度整理,方便大家閱讀。各部分所存儲的內容下面詳細了解下jvm內存模型的三個組成部分:
  • 聊到JVM(還怕面試官問JVM嗎?)
    );    }    public void a() {        b();    }    public void b() {        a();    }}最開始,main()方法壓入棧中,然後執行a(),a()壓入棧中;再調用b(),b()壓入棧中;以此往復,a與b方法不斷被壓入棧中
  • 談談java的棧和堆
    先用一張圖展示一下Java堆棧的概況堆方法區:class文件信息,運行時常量池,以及編譯器編譯後的代碼堆:存儲對象,對象包含類的信息,指向方法區>棧虛擬機棧:表示Java方法執行的內存模型,每調用一個方法就會為每個方法生成一個棧幀(Stack Frame),用來存儲局部變量表、操作數棧、動態連結、方法出口等信息。
  • java線程前傳——jvm內存結構、內存模型和cpu結構
    L2一級緩存分兩種,分別叫數據緩存(L1 D),指令緩存(L1 i)CPU肯定是需要和內存交互的,這個過程是少不了的一個線程肯定是要運行在一個核上的,多個線程可以運行在不同的核上,這個時候,因為緩存的存在,如果沒有同步機制,那一個線程修改了緩存的數據,另一個線程也修改了緩存的數據,這個時候這兩個線程修改後的數據都需要寫入到內存當中,就會出現問題jvm
  • JVM中的五大內存區域劃分詳解及快速掃盲
    簡單用一張圖來理解這三個的關係:3. jvm的組成成分不了解jvm的同學看到這張圖後可能會有點懵逼,不過沒關係,放這張圖只是想讓你了解jvm中有三塊內容非常重要,1.java代碼如何執行?JVM規範中並不區分方法區和堆,只把方法區描述為堆的邏輯部分,但是它卻有一個別名叫做非堆(Non-Heap),目的就是與Java堆區分開。
  • JVM、GC 大串講,面試夠用了
    每個方法在執行的時候都會創建一個棧,每一個方法被調用的過程就對應一個棧幀在虛擬機棧中從入棧到出棧的過程。它存儲局部變量表、操作數棧,方法出口等信息。局部變量表的大小在編輯期間完成,所以進入執行方法時,棧的大小是確定的。
  • JVM-概述和內存區域
    舉個例子將groovy編譯之後的class文件用jvm運行1、先配置好groovy環境方法區和堆區是所有線程共享的內存區域;Java棧又叫做jvm虛擬機棧。執行引擎等同於翻譯class文件的語言翻譯器。
  • 想理解JVM看了這篇文章,就知道了!
    本次將對jvm有更深入的學習,我們不僅要讓程序能跑起來,而且是可以跑的更快!可以分析解決在生產環境中所遇到的各種「棘手」的問題,比如運行的應用卡住了,日誌不輸出,程序沒有反應,CPU負載突然升高,多線程應用下,如何分配線程數量等。
  • JDK、JRE、JVM,是什麼關係?
    jvm.dll可能你之前並沒有注意過 jvm 原來在這裡:C:\Program Files\Java\jdk1.8.0_45\jre\bin\server這部分是整個 Java 實現跨平臺的最核心內容,由 Java 程序編譯成的 .class 文件會在虛擬機上執行。另外在 JVM 解釋 class 文件時需要調用類庫 lib。
  • 13道 常見的JVM 面試題
    4、Java 中堆和棧有什麼區別JVM 中堆和棧屬於不同的內存區域,使用目的也不同。棧常用於保存方法幀和局部變量,而對象總是在堆上分配。棧通常都比堆小,也不會在多個線程之間共享,而堆被整個 JVM 的所有線程共享。棧是一塊和線程緊密相關的內存區域。每個線程都有自己的棧內存,用於存儲本地變量,方法參數和棧調用,一個線程中存儲的變量對其它線程是不可見的。
  • 走進C語言:堆、棧與堆區、棧區,你知道有什麼區別嗎?
    2、棧區、堆區 則是內存模型的叫法。 5個區:棧區、堆區、靜態區、常量區、代碼區。每個區存儲的內容如下: 1、棧區:存放函數的參數值、局部變量等,由編譯器自動分配和釋放,通常在函數執行完後就釋放了,其操作方式類似於數據結構中的棧。棧內存分配運算內置於CPU的指令集,效率很高,但是分配的內存量有限,比如iOS中棧區的大小是2M。
  • Java實現單鍊表、棧、隊列三種數據結構
    2、下面是單鍊表的幾個特點:數據元素在內存中存放的地址是不連續的:單鍊表的結點裡面還定義一個結點,它裡面保存著下一個結點的內存地址,在實例化對象的時候,jvm會開闢不同內存空間,並且是不連續的。二、棧(Stack)1、一提到棧我們腦海就會浮現四個字「先進後出」,沒錯,它就是棧的最大特點。
  • 這一定是全網寫JVM最好的文章之一—JVM運行時數據區
    JVM標準加上實現了一大堆類庫,就組成了Java的運行時環境,也就是我們常說的JREJDK:玩過Java的小夥伴應該都用過java -jar,javac等命令吧,如果只有jvm,jre,我們代碼是寫完了,但是怎麼編譯呢?或者代碼出了問題怎麼調試呢?
  • 內存分配的三種情況解析:靜態、棧區、堆區
    打開APP 內存分配的三種情況解析:靜態、棧區、堆區 佚名 發表於 2017-12-15 11:26:02 內存分配分為三種:靜態、棧區、堆區分別解釋 (1)靜態存儲區:主要存放static靜態變量、全局變量、常量。
  • 面經手冊 · 第23篇《JDK、JRE、JVM,是什麼關係?》
    四、總結五、系列推薦一、前言截至到這已經寫了22篇面經手冊,你看了多少?😄其實小傅哥就是借著面經的幌子在講 Java 核心技術,探索這些核心知識點面試的背後到底在問什麼。jvm.dll 並不能獨立工作,當 jvm.dll 啟動後,會使用 explicit 方法來載入輔助動態連結庫一起執行。3. JDK 是什麼?綜上通過 Java 平臺標準和 JDK 的目錄結構,JDK 是 JRE 的超集,JDK 包含了 JRE 所有的開發、調試以及監視應用程式的工具。
  • 一條進程的棧區、堆區、數據區和代碼區在內存中的映射
    l棧區:主要用來存放局部變量,傳遞參數,存放函數的返回地址。.esp始終指向棧頂,棧中的數據越多, esp的值越小。注意:1)堆向高內存地址生長;2)棧向低內存地址生長;3)堆和棧相向而生,堆和棧之間有個臨界點,稱為stkbrk。1、一條進程在內存中的映射假設現在有一個程序,它的函數調用順序如下:main(...)
  • JVM內存區域之線程私有區域
    每一個方法被調用直至執行完畢的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。我們來通過一段非常簡短的代碼來演示虛擬機棧的作用:當我們運行main方法,虛擬機會開啟一個線程,同時為當前線程劃分一塊內存區域作為當前線程的虛擬機棧。同時在執行每個方法的時候都會打包成一個棧幀。
  • 「原創」JVM系列03|Java棧—方法是如何調用的?
    上一篇介紹 Java 虛擬機結構時講到 Java 棧同 Java 方法的調用密切相關,那麼這篇就來探究下 Java 棧到底和方法的調用有什麼關係。棧幀線程被創建的時候 Java 棧被創建,Java 棧中保存著棧幀。線程中方法被調用時,對應著一個棧幀被壓入 Java 棧;方法返回時,對應的棧幀從 Java 棧中彈出;方法中拋出異常時,對應的棧幀也會將棧幀彈出。