1. 程式人生 > >JVM管理記憶體空間堆和棧的區別

JVM管理記憶體空間堆和棧的區別

  在說堆和棧之前,我們先說一下JVM(虛擬機器)記憶體的劃分:

      Java程式在執行時都要開闢空間,任何軟體在執行時都要在記憶體中開闢空間,Java虛擬機器執行時也是要開闢空間的。JVM執行時在記憶體中開闢一片記憶體區域,啟動時在自己的記憶體區域中進行更細緻的劃分,因為虛擬機器中每一片記憶體處理的方式都不同,所以要單獨進行管理。

      JVM記憶體的劃分有五片:

       1.   暫存器;

       2.   本地方法區;

       3.   方法區;

       4.   棧記憶體;

       5.   堆記憶體。

       我們重點來說一下堆和棧:

       棧記憶體:棧記憶體首先是一片記憶體區域,儲存的都是區域性變數,凡是定義在方法中的都是區域性變數(方法外的是全域性變數),for迴圈內部定義的也是區域性變數,是先載入函式才能進行區域性變數的定義,所以方法先進棧,然後再定義變數,變數有自己的作用域,一旦離開作用域,變數就會被釋放。棧記憶體的更新速度很快,因為區域性變數的生命週期都很短。

       堆記憶體:儲存的是陣列和物件(其實陣列就是物件),凡是new建立的都是在堆中,堆中存放的都是實體(物件),實體用於封裝資料,而且是封裝多個(實體的多個屬性),如果一個數據消失,這個實體也沒有消失,還可以用,所以堆是不會隨時釋放的,但是棧不一樣,棧裡存放的都是單個變數,變數被釋放了,那就沒有了。堆裡的實體雖然不會被釋放,但是會被當成垃圾,Java有垃圾回收機制不定時的收取。

      下面我們通過一個圖例詳細講一下堆和棧:

      比如主函式裡的語句   int [] arr=new int [3];在記憶體中是怎麼被定義的:

      主函式先進棧,在棧中定義一個變數arr,接下來為arr賦值,但是右邊不是一個具體值,是一個實體。實體建立在堆裡,在堆裡首先通過new關鍵字開闢一個空間,記憶體在儲存資料的時候都是通過地址來體現的,地址是一塊連續的二進位制,然後給這個實體分配一個記憶體地址。陣列都是有一個索引,陣列這個實體在堆記憶體中產生之後每一個空間都會進行預設的初始化(這是堆記憶體的特點,未初始化的資料是不能用的,但在堆裡是可以用的,因為初始化過了,但是在棧裡沒有),不同的型別初始化的值不一樣。所以堆和棧裡就建立了變數和實體:

                                                  

     那麼堆和棧是怎麼聯絡起來的呢?

     我們剛剛說過給堆分配了一個地址,把堆的地址賦給arr,arr就通過地址指向了陣列。所以arr想操縱陣列時,就通過地址,而不是直接把實體都賦給它。這種我們不再叫他基本資料型別,而叫引用資料型別。稱為arr引用了堆記憶體當中的實體。(可以理解為c或c++的指標,Java成長自c++和c++很像,優化了c++)                                                                

              如果當int [] arr=null;

              arr不做任何指向,null的作用就是取消引用資料型別的指向。

              當一個實體,沒有引用資料型別指向的時候,它在堆記憶體中不會被釋放,而被當做一個垃圾,在不定時的時間內自動回收,因為Java有一個自動回收機制,(而c++沒有,需要程式設計師手動回收,如果不回收就越堆越多,直到撐滿記憶體溢位,所以Java在記憶體管理上優於c++)。自動回收機制(程式)自動監測堆裡是否有垃圾,如果有,就會自動的做垃圾回收的動作,但是什麼時候收不一定。

             所以堆與棧的區別很明顯:

            1.棧記憶體儲存的是區域性變數而堆記憶體儲存的是實體;

            2.棧記憶體的更新速度要快於堆記憶體,因為區域性變數的生命週期很短;

            3.棧記憶體存放的變數生命週期一旦結束就會被釋放,而堆記憶體存放的實體會被垃圾回收機制不定時的回收。

相關推薦

JVM管理記憶體空間區別

  在說堆和棧之前,我們先說一下JVM(虛擬機器)記憶體的劃分:      Java程式在執行時都要開闢空間,任何軟體在執行時都要在記憶體中開闢空間,Java虛擬機器執行時也是要開闢空間的。JVM執行時在記憶體中開闢一片記憶體區域,啟動時在自己的記憶體區域中進行更細緻的劃分,

1.1JVM記憶體結構——、方法區、直接記憶體區別

一、定義 1、堆:FIFO佇列優先,先進先出。jvm只有一個堆區被所有執行緒所共享!堆存放在二級快取中,呼叫物件的速度相對慢一些,生命週期由虛擬機器的垃圾回收機制定。2、棧:FILO先進後出,暫存資料的地方。每個執行緒都包含一個棧區!棧存放在一級快取中,存取速度較快,“棧是限

、方法區、直接記憶體區別

       新生區是類的誕生、成長、消亡的區域,一個類在這裡產生,應用,最後被垃圾回收器收集,結束生命。新生區又分為兩部分:伊甸區(Eden space)和倖存者區(Survivor pace),所有的類都是在伊甸區被new出來的。倖存區有兩個:0區(Survivor 0 space)和1區(Survivo

資料結構記憶體區別

特別宣告:本文參考了部落格:http://blog.csdn.net/wolenski/article/details/7951961#comments        堆和棧在 我的眼裡一直是很模糊的概念,只是簡單的理解為:堆疊是一種資料結構,是用來儲存資料的。由於最近

作業系統課程中記憶體裡面區別

http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html首先需要宣告,這個連結裡面有比較詳細的描述,但是有點長,下面我簡單的描述一下,讓大家快速的瞭解這個知識。  我們在組合語言中或是在作業系統課堂上經常

記憶體區別

原文: http://student.csdn.net/link.php?url=http://www.top-e.org%2Fjiaoshi%2Fhtml%2F427.html 在計算機領域,堆疊是一個不容忽視的概念,我們編寫的C語言程式基本上都要用到。但對於很多的初學著

區別 學習整理1

原文 有些地方還沒有完全理解收藏學習 堆和棧的區別一、預備知識—程式的記憶體分配一個由c/C++編譯的程式佔用的記憶體分為以下幾個部分1、棧區(stack)— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2、堆區(heap)

C++中的記憶體區域——的比較

參考連結:https://blog.csdn.net/sdfgh2046/article/details/5830807                   https://blog.csdn.n

區別 生長方向

C++作為一款C語言的升級版本,具有非常強大的功能。它不但能夠支援各種程式設計風格,而且還具有C語言的所有功能。我們在這裡為大家介紹的是其中一個比較重要的內容,C++記憶體區域的基本介紹。 C++記憶體區域分為5個區域。分別是堆,棧,自由儲存區,全域性/靜態儲存區和常量

Java中區別

在函式中定義的一些基本型別的變數和物件的引用變數都在函式的棧記憶體中分配。      當在一段程式碼塊定義一個變數時,Java就在棧中為這個變數分配記憶體空間,當超過變數的作用域後,Java會自動釋放掉為該變數所分配的記憶體空間,該記憶體空間可以立即被另作他用。  

利用動態規劃演算法解01揹包問題->二維陣列傳參->cpp記憶體管理->區別->常見的記憶體錯誤及其對策->指標陣列的區別->32位系統是4G

1、利用動態規劃演算法解01揹包問題 https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html 兩層for迴圈,依次考察當前石塊是否能放入揹包。如果能,則考察放入該石塊是否會得到當前揹包尺寸的最優解。 // 01 knap

JVM記憶體結構------,方法區,以及區別

一 、 定義 堆:FIFO佇列優先,先進先出。JVM只有一個堆區被所有執行緒所共享!堆存放在耳機快取中,呼叫物件的速度相對慢一些,生命週期由JVM的垃圾回收機制定。 棧:FILO先進後出,暫存資料的地方。每個執行緒都包含一個棧區!棧存放在一級快取中,存取速度較快,“棧是限定

記憶體管理區別

不知道誰寫的,很詳細,對了解程式資料儲存有一定幫助,轉載過來自己學習同時與眾分享。 一、預備知識―程式的記憶體分配 一個由C/C++編譯的程式佔用的記憶體分為以下幾個部分 1、棧區(stack)― 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。 2、堆區

作業系統記憶體管理之 ---區別

一、預備知識—程式的記憶體分配 一個由C/C++編譯的程式佔用的記憶體分為以下幾個部分 (從上到下,從記憶體高地址到記憶體低地址) 1、棧區(stack) — 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。

Android記憶體優化六:系統中使用管理記憶體區別

一直對系統中堆和棧的使用原則不太理解,在網上看到這篇文章,非常不錯! 轉載地址:http://bbs.csdn.net/topics/390147637 在計算機領域,堆疊是一個不容忽視的概念,我們編寫的C語言程式基本上都要用到。但對於很多的初學著來說,堆疊是一個很模糊的概

JVM】Java記憶體詳解:區別

最近在研究多執行緒的東西,看到了Java記憶體的相關知識。又回到了堆和棧這個話題,在很早之前就研究過,只知道這兩種資料結構一個是先進後出,一個是先進先出,借這個機會,再細緻研究一下,對比二者的不同: Java把記憶體劃分為兩種:一種是棧記憶體,一種是堆記憶體。

記憶體分配方式以及區別

轉載:https://blog.csdn.net/shanchangyi/article/details/51854795 對於一個程式要執行,涉及到的記憶體分配是一個首要問題,這裡簡單說一下一個簡單的程式執行所涉及到的記憶體分配方式。另外,在資料結構中存在堆和棧的概念,棧是一種先進後出的資料結

C/C++ 全域性變數區域性變數在記憶體裡的區別

一、預備知識—程式的記憶體分配  一個由c/C++編譯的程式佔用的記憶體分為以下幾個部分  1、棧區(stack)— 由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧,如果還不清楚,那麼就把它想成陣列,它的記憶體分

C++記憶體管理學習

一 C++記憶體管理 1.記憶體分配方式    在講解記憶體分配之前,首先,要了解程式在記憶體中都有什麼區域,然後再詳細分析各種分配方式。 1.1 C語言和C++記憶體分配區   下面的三張圖,圖1圖2是一種比較詳細的C語言的記憶體區域分法。圖3是典型的C++記憶體分佈圖,簡單易懂;以

記憶體管理

關於程式的執行,不得不提到記憶體方面的內容,那麼首先就對一個程序虛擬地址空間的佈局用一張圖來看清楚 這張圖基於32位Linux系統,即起始地址為0x08048000,可以看到順序為只讀段(程式碼段等)、讀寫段(資料段、bss段等)、堆(向上即高地址擴充套件)、用於堆擴充套件的未使用空間、動態庫的對