1. 程式人生 > >JVM棧和堆的詳解

JVM棧和堆的詳解

com 你會 分享圖片 緩存 運行 基本數據類型 margin jvm png

一、基本了解

java的數據類型分為兩種:基本類型和引用類型。基本類型的變量保存的是原始值,引用類型的變量保存的是引用值。引用值代表某個對象的引用,而不是對象本身,對象本身放在這個引用值所表示的地址的位置。

二、堆與棧

技術分享圖片

三、詳細說明

棧是運行時的單位,堆是存儲的單位

棧解決的程序運行問題,即程序如何執行,或者說如何處理數據;堆解決的是數據存儲問題,即就是數據如何放、放哪兒

在java中一個線程就會相應有一個線程棧與之對應,因為不同的線程執行邏輯有所不同,因此需要一個獨立的線程棧。堆是所有線程共享的。棧因為是運行單位。因此裏面存儲的是和當前線程相關的數據。包括局部變量、程序運行狀態、方法返回值等;而堆只負責存儲對象信息。

為什麽要將堆和棧分開,棧不是也可以存儲數據嗎?

1、從軟件設計角度分析,棧代表了處理邏輯,堆代表了數據,這樣分開,使得處理邏輯更清晰。分而治之的思想,這種隔離、模塊化的思想體現在軟件中的很多地方。

2、堆和棧的分離,使得堆的內容可以被多個棧共享(即多個線程訪問同一個對象)。這種共享的收益很多,這種共享提供了一種有效的數據交互方式(共享內存),另一方面,堆中共享的常量和緩存可以被所有棧訪問,節省了內存。

3、棧因為運行是需要,比如保存系統運行的上下文,需要地址段的劃分,由於棧只能向上增長,因此限制住棧存儲內容的能力,而堆是根據需要可以動態增長的,因此棧和堆的拆分,使得堆動態增長成為可能,相應棧只需要記住堆中的一個地址即可。

4、面向對象就是堆和棧的完美結合。其實,面向對象方式的程序與以前結構化的程序在執行上沒有任何區別。但是,面向對象的引入,使得對待問題的思考方式發生了改變,而更接近於自然方式的思考。當我們把對象拆開,你會發現,對象的屬性其實就是數據,存放在堆中;而對象的行為(方法),就是運行邏輯,放在棧中。我們在編寫對象的時候,其實即編寫了數據結構,也編寫的處理數據的邏輯。不得不承認,面向對象的設計,確實很美

在java中,main函數是棧的起始點,也是程序的起始點。

堆中存什麽,棧中存什麽?

堆中存的是對象,棧中存的是基本數據類型和堆中對象的引用,一個對象的大小不可以估計,或者說是可以動態變化的,但是在棧中,一個對象只對應了一個4byte引用

對象,從某種意義上說,是由基本類型組成的。可以把一個對象看作為一棵樹,對象的屬性如果還是對象,則還是一顆樹(即非葉子節點),基本類型則為樹的葉子節點。程序參數傳遞時,被傳遞的值本身都是不能進行修改的,但是,如果這個值是一個非葉子節點(即一個對象引用),則可以修改這個節點下面的所有內容。
堆和棧中,棧是程序運行最根本的東西。程序運行可以沒有堆,但是不能沒有棧。而堆是為棧進行數據存儲服務,說白了堆就是一塊共享的內存。不過,正是因為堆和棧的分離的思想,才使得Java的垃圾回收成為可能。

Java中,棧的大小通過-Xss來設置,當棧中存儲數據比較多時,需要適當調大這個值,否則會出現java.lang.StackOverflowError異常。常見的出現這個異常的是無法返回的遞歸,因為此時棧中保存的信息都是方法返回的記錄點

JVM棧和堆的詳解