如何準確理解Java中的堆與棧

2020-12-15 宅習社

關於內存可以說是Java中的重要概念,而棧和堆又是內存中的兩個重要部分。怎樣理解棧和堆?棧可以理解為內存中一片連續的區域,而堆可以理解為內存中一片分散的區域。可以說,棧是用來運行程序的區域,當在棧裡應用一個值的時候,這個值就會指向堆中的一個位置。其實可以理解為一種函數關係。在進一步理解堆和棧的關係,則要先理解一下Java虛擬機。

在學Java的過程中,有些人會寫代碼,但對數據的來源並不清楚,代碼是怎樣運行和實現的,和JVM也有著密切的關係。

一個Java程序需要在Java虛擬機(JVM)上運行才能得以實現,當java程序啟動時,java虛擬機也會自動地開啟,當java程序的所有線程都結束的時候,自然而然的,載體也會停止工作。

jvm在啟動時,會開啟虛擬機自身的線程,例如垃圾回收線程,還有java程序的線程,創建的線程名,同時創建對象和變量,這些都會放在JVM的棧中,而線程對象字符串,new的對象,變量,都會放在堆中;最後,變量的值,則會放在方法中,方法區和堆都是共享的,通過以上的敘述,就可以看出一些JVM的運行機制。

如果從數據的調用方面和對象的創建方面來說的話,堆,棧,方法區,是一個整體存在的東西,例如,一個String b=new String(「test」); 我現在new了一個對象b這個對象名放在棧中,b這個對象值(對象字符串)放在堆中,"test"就會放到方法區中,這樣的分工機制有效提升了程序運行的速度。

由此可見,堆是java應用程式最密切的內存空間。可以說所有的對象都存在堆中。而且堆的管理是自動化的,通過GC回收機制,垃圾對象會自動清理,不需要顯式釋放。

因為垃圾回收機制各不相同,所以java堆可能有不同的結構。最常見的是將整個java堆分為新生代和老年代。尚學堂陳老師指出,老年代的數據最終要被消除,新生代存放新對象或者年齡不大的對象,老年代存放老年對象。新生代有可能分為eden區、s0區和s1區,s0區和s1區也被稱之為 from 到to區域。

一般情況下,對象首先被分配在eden區,再一次新生代回收後,如果對象還存在,則會進入s0或者s1,而當對象年齡達到一定條件後,就會老齡化進入老年代。

以上就是對Java中堆與棧的理解,希望對正在學Java的朋友有所幫助。

相關焦點

  • 認識Java虛擬機的堆和棧
    關於運行數據區的堆堆是在運行數據區劃分出來的一塊內存區域,用於存儲在程序運行過程中創建的對象實例和數組,在虛擬機運行的所有線程創建的對象實例和數組都共享一個堆。堆中的存儲空間是有限的,當堆中存儲的對象實例超過堆的存儲空間時,堆就無法再存儲新的實例對象,在這種情況下就會造成堆的溢出,java程序也會拋出內存溢出異常。因此當堆中的實例對象不再需要時,應及時回收空間,回收的空間再分配給新的實例對象。那麼,在什麼情況下要對堆中的實例對象進行回收呢?
  • 深入分析Java虛擬機堆和棧及OutOfMemory異常產生原因
    調用String.intern()方法,首先還是會去常量池中檢查是否存在,如果不存在,那麼就會創建一個常量,並將引用指向堆,也就是說不會再重新創建一個字符串對象了,兩者都會指向堆中的對象,所以返回true。
  • 堆與棧:JAVA和c++內存分配的區別
    靜態存儲分配要求在編譯時能知道所有變量的存儲要求,棧式存儲分配要求在過程的進口處必需知道所有的存儲要求,而堆式存儲分配則專門負責在編譯時或運行時模塊進口處都無法確定存儲要求的數據結構的內存分配,好比可變長度串和對象實例。堆由年夜片的可操作塊或餘暇塊組成,堆中的內存可以按照肆意挨次分配和釋放。
  • 一張圖讀懂jvm之運行時數據區-堆、棧、以及程序計數器
    下面,我們來看下這張圖:運行時數據區分為:pc(program counter)寄存器、java 虛擬機棧、堆、方法區、運行時常量池、本地方法棧。其中,運行時常量池屬於方法區,下面是各自的詳細介紹。java 虛擬機棧與線程同時創建,存儲棧幀,棧裡面存放的數據是:局部變量與一些尚未計算好的結果。
  • 堆和棧的區分
    不管你是學習c語言,還是學習c++,亦或是學習java,你都會遇到內存分配的問題,而對於內存分配,它其實有兩個地方,一個地方叫做堆,一個地方叫做棧,什麼時候將數據存放到堆上面,什麼時候將數據存放到棧上面,它們的區別是什麼,今天我們就來詳細講解一下。
  • java中棧(stack)堆(heap)靜態區(static area)概念
    對於java的這3大區域了解下還是有必要的,尤其是對jvm調優,更應該理解下它們的概念。這種隔離、模塊化的思想在軟體設計的方方面面都有體現;第二:堆與棧的分離,使得堆中的內容可以被多個棧共享(也可以理解為多個線程訪問同一個對象)。這種共享的收益是很多的。
  • 談談java的棧和堆
    先用一張圖展示一下Java堆棧的概況堆方法區:class文件信息,運行時常量池,以及編譯器編譯後的代碼堆:存儲對象,對象包含類的信息,指向方法區>棧虛擬機棧:表示Java方法執行的內存模型,每調用一個方法就會為每個方法生成一個棧幀(Stack Frame),用來存儲局部變量表、操作數棧、動態連結、方法出口等信息。
  • Java堆內存的10個要點
    對於程式設計師來說,知道堆空間,設置堆空間,處理堆空間的outOfMemoryError錯誤,分析heap dump是非常重要的。這個關於Java堆的教程是給我剛開始學編程的兄弟看的。如果你知道這個基礎知識或者知道底層發生了什麼,當然可能幫助不是那麼大。除非你知道了對象被創建在堆中,否則你不會意識到OutOfMemoryError是發生在堆空間中的。
  • 「原創」JVM系列03|Java棧—方法是如何調用的?
    棧幀線程被創建的時候 Java 棧被創建,Java 棧中保存著棧幀。線程中方法被調用時,對應著一個棧幀被壓入 Java 棧;方法返回時,對應的棧幀從 Java 棧中彈出;方法中拋出異常時,對應的棧幀也會將棧幀彈出。
  • 使用java定義一個具備棧功能的類
    棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入和刪除運算。這一端被稱為棧頂,相對地,把另一端稱為棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。
  • C語言編程中的「堆」和「棧」七大不同之處
    對於編程初學者來說會接觸到一些難以理解的名稱,比如堆(heap)、棧(stack)、堆棧(stack)等。初學開發過程中往往讓人混淆不清。
  • 數據結構中的棧,你知道多少?
    由於棧比較簡單,也很容易理解,學過的人都知道一句話就可以描述棧的特性:後進先出。所以這篇文章主要是寫如何使用代碼來描述棧,當然也是讓大家很容易理解的語言。還是先給出這篇文章的大致脈絡。因此在這裡我們不需要定義節點,在這裡用java代碼實現順序棧有兩個步驟,第一:定義棧的接口,接口內部定義了棧的常用操作方法第二:然後就是接口的實現了。下面按照這個步驟一步一步來看。
  • 「原創」JVM系列02|Java虛擬機結構
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫Java虛擬機學習 Java 虛擬機,先要掌握其基本結構,了解各部分有什麼作用,各部分之間是如何協調工作的。
  • JVM中的五大內存區域劃分詳解及快速掃盲
    簡單用一張圖來理解這三個的關係:3. jvm的組成成分不了解jvm的同學看到這張圖後可能會有點懵逼,不過沒關係,放這張圖只是想讓你了解jvm中有三塊內容非常重要,1.java代碼如何執行?2.內存如何管理?3.線程資源如何利用?腦袋裡有個印象即可,帶著問題去學習。4. 運行java文件的大概流程想要運行java的源文件,必須要經過javac編譯器編譯成.class文件,也就是字節碼文件。
  • 走進C語言:堆、棧與堆區、棧區,你知道有什麼區別嗎?
    一、區別 註:首先堆和棧可以分為兩種,一種是數據結構,另一種是和內存的分配有關,這兩種雖然都有棧和堆,但是兩者關係並不大, 1、棧、堆是數據結構裡面的叫法,注意:有時候有人喜歡這樣說 「堆棧」 其實說的就是棧而不是堆。
  • Java面試總結之Full GC
    在面試中我們會經常被問到full Gc相關的問題,比如什麼情況下會發生full gc,如何去排查頻繁發生full Gc的問題等。要想輕鬆自如的回答這些問題,我們就必須充分的去理解gc的觸發條件,gc回收的內容,以及gc具體的執行過程。掌握了這3個要點,full gc相關的問題就易如反掌了。
  • 零基礎java入門教程java數組選擇排序冒泡排序和java內置排序
    特別注意,排序中最快的方法是希爾排序;希爾排序是三層循環加上位運算來排的序。因為:每一次符合條件,咱們都會在數組當中對數組元素的位置的置換而堆內存中換位置比較消耗資源,但這消耗的資源也不是特別的大;如果說他們需要換位置的話我們先不置換他們的位置?
  • IT挑戰高薪開發常識-為什麼把堆和棧區分開來?
    (2)堆與棧的分離,使得堆中的內容可以被多個棧共享(也可以理解為多個線程訪問同一個對象)。這種共享的效益是顯著的。一方面這種共享提供了一種有效的數據交互方式(如:共享內存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節省了空間。
  • 關於PHP語言在內存中的分配(堆和棧的區別)
    分享關於編程中的數據在內存裡的存儲方式,本文以PHP語言為例來分析計算機中各段存儲區的區別,代碼段、堆空間段、代碼段、初始化靜態常量段。棧空間段:是存儲佔用相同空間長度並且佔用空間小的數據類型的地方,比如說整型1,10,100,1000,10000,100000 等等,在內存裡面佔用空間是等長的,都是64 位4 個字節。存儲的都是局部變量,凡是定義在方法中的都是局部變量(方法外的是全局變量),變量有自己的作用域,一旦離開作用域,變量就會被釋放。
  • python:棧的理解與應用
    如何理解「棧」?關於「棧」,我有一個非常貼切的例子,就是一摞疊在一起的盤子。我們平時放盤子的時候,都是從下往上一個一個放;取的時候,我們也是從上往下一個一個地依次取,不能從中間任意抽出。後進者先出,先進者後出,這就是典型的「棧」結構。