認識Java虛擬機的堆和棧

2020-12-15 米粒教育

關於運行數據區的堆

堆是在運行數據區劃分出來的一塊內存區域,用於存儲在程序運行過程中創建的對象實例和數組,在虛擬機運行的所有線程創建的對象實例和數組都共享一個堆。

堆中的存儲空間是有限的,當堆中存儲的對象實例超過堆的存儲空間時,堆就無法再存儲新的實例對象,在這種情況下就會造成堆的溢出,java程序也會拋出內存溢出異常。因此當堆中的實例對象不再需要時,應及時回收空間,回收的空間再分配給新的實例對象。

那麼,在什麼情況下要對堆中的實例對象進行回收呢?開發者可以使用new運算符在堆中創建實例對象,但不能釋放已創建的實例對象。其實開發者不需要考慮如何回收實例對象佔用的存儲空間,虛擬機的垃圾收集器(垃圾收集器在後面的課程會講到)會自動回收不再被運行的程序引用的對象所佔用的存儲空間。

關於運行數據區的棧

棧是一個數據結構,棧結構是一種特殊的線性表,限定僅在表的一端進行元素的插入和刪除。當表中沒有元素時,稱為空棧。若給定棧:

S = (a1,a2,……,an)

則稱a1是棧底元素,an是棧頂元素,表中元素按a1,a2,……,an的次序進棧,出棧的順序是an,……,a2,a1。也就是說,棧結構的元素訪問原則是後進先出,也稱為後進先出的線性表的,如下圖所示。

棧結構圖

棧也是在運行數據區劃分出來的一塊內存區域,棧是和線程相關的,虛擬機會為每個線程分配一個棧,棧以幀為單位保存線程的運行狀態,一個棧幀保存了Java方法的參數、局部變量、中間運算結果、返回值等數據。棧幀由局部變量區、操作數棧和棧數據區構成。當線程調用一個Java方法時,虛擬機會從方法所在的類信息中得知此方法的局部變量區和操作數棧的大小,並給棧幀分配內存,將棧幀壓入棧中。

每當線程調用一個方法時,虛擬機都會在該線程的棧中壓入一個棧幀,這個棧幀為當前棧幀。Java方法有兩種返回方式:一種是方法運行完成後,以return方式返回;一種是在方法運行過程中,發生錯誤拋出異常,非正常返回。不管以哪種方式返回,虛擬機都會將當前棧幀彈出並釋放掉,這樣上一個方法的棧幀就成為當前棧幀了。

堆和棧的關係

堆是存儲實例對象和數組的內存區域,棧是存儲線程內類方法運行狀態的內存區域。當線程調用類方法時,與方法有關的類變量和方法內部的局部變量都會存儲到棧幀,當這些類變量和局部變量是對象引用變量時,這些變量會指向堆中的實例對象或數組,方法執行完成後,與方法相關的棧幀被彈出棧,棧幀佔用的存儲空間被釋放,但堆中的實例對象或數組並沒有釋放,它們由垃圾收集器在隨後的時間進行釋放。

棧幀和堆的關係圖

相關焦點

  • 深入分析Java虛擬機堆和棧及OutOfMemory異常產生原因
    Heap(堆)堆是Java虛擬機所管理內存中最大的一塊,在虛擬機啟動時創建,被所有線程共享。堆在虛擬機啟動時創建,用於存儲所有的對象實例和數組(在某些特殊情況下不是)。堆中的對象永遠不會顯式地釋放,必須由GC自動回收。
  • 如何準確理解Java中的堆與棧
    關於內存可以說是Java中的重要概念,而棧和堆又是內存中的兩個重要部分。怎樣理解棧和堆?棧可以理解為內存中一片連續的區域,而堆可以理解為內存中一片分散的區域。可以說,棧是用來運行程序的區域,當在棧裡應用一個值的時候,這個值就會指向堆中的一個位置。其實可以理解為一種函數關係。
  • 「原創」JVM系列02|Java虛擬機結構
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫Java虛擬機學習 Java 虛擬機,先要掌握其基本結構,了解各部分有什麼作用,各部分之間是如何協調工作的。
  • 堆與棧:JAVA和c++內存分配的區別
    棧式存儲分配也可稱為動態存儲分配,是由一個近似於倉庫的運行棧來實現的。和靜態存儲分配相反,在棧式存儲方案中,對數據區的需求在編譯時是完全未知的,只有到運行的時辰才能夠知道,可是劃定在運行中進入一個軌範模塊時,必需知道該軌範模塊所需的數據區巨細才能夠為其分配內存。和我們在數據結構所熟知的棧一樣,棧式存儲分配按照前進前輩後出的原則進行分配。
  • 一張圖讀懂jvm之運行時數據區-堆、棧、以及程序計數器
    你知道 java 程序在運行時數據是存儲在哪裡的嗎?比如,常量數據,臨時計算結果,你知道棧溢出和內存不足是怎麼一回事嗎?關注我,帶你一起走進 jvm,原創不易,記得關注 + 收藏哦。java 虛擬機棧與線程同時創建,存儲棧幀,棧裡面存放的數據是:局部變量與一些尚未計算好的結果。
  • 一篇文章全面吃透Java虛擬機,線程安全的實現方法
    01前言jvm虛擬機包含堆,棧,本地方法棧,類裝載子系統,方法區,程序計數器也就是字節碼執行引擎。其中運行時數據區包含即內存模型包含堆,棧,本地方法棧。即類裝載子系統。我們的代碼調優也主要是在堆內存中進行。
  • 堆和棧的區分
    不管你是學習c語言,還是學習c++,亦或是學習java,你都會遇到內存分配的問題,而對於內存分配,它其實有兩個地方,一個地方叫做堆,一個地方叫做棧,什麼時候將數據存放到堆上面,什麼時候將數據存放到棧上面,它們的區別是什麼,今天我們就來詳細講解一下。
  • 談談java的棧和堆
    先用一張圖展示一下Java堆棧的概況堆方法區:class文件信息,運行時常量池,以及編譯器編譯後的代碼堆:存儲對象,對象包含類的信息,指向方法區>棧虛擬機棧:表示Java方法執行的內存模型,每調用一個方法就會為每個方法生成一個棧幀(Stack Frame),用來存儲局部變量表、操作數棧、動態連結、方法出口等信息。
  • 程式設計師每日一題-jvm裡方法和方法區、棧區的二三事
    JAVA虛擬機運行時數據區的邏輯圖好,對照上圖,逐項解釋A:堆區是JVM 所管理的內存中最大的一塊。線程共享,主要是存放對象實例和數組。堆區是jvm裡面最需要深入研究的一塊區域,這裡面涉及內存分配,區域劃分,對象信息,垃圾回收。可以說如果java程式設計師對堆區不熟悉,那麼一定寫不出好的代碼。本文暫時不深入討論,後續會開專題深入講解。B:棧區,也叫虛擬機棧,顧名思義,它是一個棧,先進後出。它是線程創建時跟著創建,生命周期和線程一致,是線程私有的。
  • 「原創」JVM系列03|Java棧—方法是如何調用的?
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫本文是何適 JVM 修仙系列第 3 篇,文末有本系列文章匯總。上一篇介紹 Java 虛擬機結構時講到 Java 棧同 Java 方法的調用密切相關,那麼這篇就來探究下 Java 棧到底和方法的調用有什麼關係。
  • 2020第一篇:堆、棧、方法區、類加載器——JVM 內存模型分析
    本地方法棧:為虛擬機使用的native方法服務,方法通常是使用C/C++編寫,然後編譯成.dll或者.so文件,再由JNI(Java Native Interface)調用執行。Java虛擬機棧:描述Java方法執行的內存模型,每個方法被執行的時候都會同時創建一個棧幀用於存儲局部變量表、操作棧、動態連結、方法出口等信息;注意是每執行一個方法就創建一個棧幀,棧幀存放了當前方法的數據信息(局部變量),方法執行完畢,該方法的棧幀就會被銷毀。
  • Java面試總結之Full GC
    作為程式設計師要關注的區域主要有5塊,分別是方法區(Method Area),Java棧(Java stack),本地方法棧(Native Method Stack),堆(Heap),程序計數器(Program Counter Register)。實際jvm在管理內存的時候,比這個分的更細緻,只不過做應用程式開發,我們只需要關注這5塊就可以了。
  • Java虛擬機應用於數位電視機頂盒的研究與實現
    結構及工作原理  Java虛擬機工作原理  Java虛擬機處於機器和編譯程序之間,在任何平臺上都提供給編譯程序一個共同的接口。Java源程序經過編譯器編譯後變成字節碼,字節碼由虛擬機解釋執行,虛擬機將每一條要執行的字節碼送給解釋器,解釋器將其翻譯成特定機器上的機器碼,然後在特定的機器上運行。
  • Java堆內存的10個要點
    如何增加Java堆空間在大多數32位機、Sun的JVM上,Java的堆空間默認的大小為128MB,但也有例外,例如在32未Solaris作業系統(SPARC平臺版本)上,默認的最大堆空間和起始堆空間大小為 -Xms=3670K 和 -Xmx=64M。對於64位作業系統,一般堆空間大小增加約30%。
  • 使用java定義一個具備棧功能的類
    棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。這一端被稱為棧頂,相對地,把另一端稱為棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。
  • java中棧(stack)堆(heap)靜態區(static area)概念
    對於java的這3大區域了解下還是有必要的,尤其是對jvm調優,更應該理解下它們的概念。為什麼把堆和棧區分出來呢?第一:從軟體設計的角度看,棧代表了處理邏輯,而堆代表了數據。這樣分開,使得處理邏輯更為清晰。分而治之的思想。
  • JVM筆記四-棧區
    JVM學習筆記之棧區本文主要內容:棧是什麼?棧幀又是什麼?在JVM中,main方法調用say方法後,是怎麼運行的?本文將詳細講解棧。希望大家學了之後,對棧有更深的了解。心法:在JVM中,棧管運行,堆管存儲。
  • 走進C語言:堆、棧與堆區、棧區,你知道有什麼區別嗎?
    一、區別 註:首先堆和棧可以分為兩種,一種是數據結構,另一種是和內存的分配有關,這兩種雖然都有棧和堆,但是兩者關係並不大, 1、棧、堆是數據結構裡面的叫法,注意:有時候有人喜歡這樣說 「堆棧」 其實說的就是棧而不是堆。