java虛擬機系列之深入認識堆(Heap)和棧(Stack)

  上一篇在介紹java虛擬機之前,我們談到了什麼是java的基本類型和引用類型,平時我們應該注意的東西,然後我們談到了java虛擬機中的堆和棧,但是也只是很簡單的說了一說,但是我覺得在java中最重要的就是理解好堆和棧,因爲java的面向對象特性我覺得跟堆和棧的分離密切相關,所以就仔細深入的談談。

1.我不知道有沒有人會疑惑,爲什麼java要把堆和棧分開呢?堆能存儲東西,難道棧就不能了嗎?在運行的時候不就是把數據放在棧中嗎?

(1)是的,確實是這樣的,正如之前所說的棧是負責運行時的,而堆是負責存儲信息的。不知道大家有沒有了解設計模式裏面的一些原則,其中有一條的爲對象之間的鬆耦合而努力,在用在這裏同樣適用,把棧和堆分離開來,可以使處理邏輯的條理更加清晰,這種原則我覺得在設計軟件的時候要注重,套用一個詞就是分而治之,後面講到的垃圾回收是不是就變得可行了呢?。

(2)從線程共享的方面來看,堆和棧的分離,可以使堆的信息是線程共享(或者說是棧共享的)的,這樣就爲多線程同時訪問一個對象提供了可能。而這樣方式對於數據交互是有效的(通過共享內存),而且堆中的共享常量和緩存可以給多個棧訪問,節約了空間。

(3)套用某個大神的話來說,面向對象就是棧和堆的完美結合。這個怎麼理解會比較好呢?認真的想一想,我們平時一般創建一個對象是不是就是把事物的特徵抽象出來,但是調用方法呢?是不是就是相當於處理一個個的邏輯,既然是邏輯是不是就是跟棧密切相關?所以說面向對象的實現跟堆和棧的結合是分不開的。

2.我們還需要重點記住的就是,在java中程序的入口一定是Main函數, 也就是棧的起點,因爲我們都是在棧中處理邏輯的

3.接下來,我們就要想一想了,到底堆中存的是什麼?棧中存的是什麼?

  對於堆中要存的數據,我覺得大家閉着眼都會,不就是一個個的對象嗎?那麼棧中存的是什麼呢?其實也很簡單,那就是上一篇我們重點講的基本數據類型,以及對堆中對象的引用,這樣來說是不是就清晰了一點。

4.Java中的參數傳遞時傳值呢?還是傳引用?

1)如果要理解這個,我覺得需要明白的一點是,在java中是沒有指針這個概念的,但是不要認爲java中就沒有使用到指針。

(2)java的程序是在棧中運行的,在傳遞參數的時候,棧中只存在傳基本類型和對對象的引用的問題,並沒有傳對象的本身。

明白了上面的兩個原則,我覺得上面的問題就不難解答了,但是我們還需要注意的一點就是,傳遞的參數如果是基本類型的話,就不能夠更改他的值,如果傳的是對象的引用,我們可以改變對象裏面的屬性,成員變量等。換而成一句話就是一個基本類型不能改變,但是有很多個基本類型組成的對象確實可以修改。

最後用一句話來總結,在java程序中,可以沒有堆,但是不能沒有棧,至於爲什麼我覺得可以思考一下,什麼是程序的入口。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章