【Java面試題】解釋內存中的棧(stack)、堆(heap)和靜態存儲區的用法


Java面試題:解釋內存中的棧(stack)、堆(heap)和靜態存儲區的用法

堆區: 專門用來保存對象的實例(new 創建的對象和數組),實際上也只是保存對象實例的屬性值,屬性的類型和對象本身的類型標記等,並不保存對象的方法(方法是指令,保存在Stack中)

1.存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令) 2.jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身. 3.一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。 

 

棧區: 對象實例在Heap 中分配好以后,需要在Stack中保存一個4字節的Heap內存地址,用來定位該對象實例在Heap 中的位置,便於找到該對象實例。

1.每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中 2.每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問。 3.棧分為3個部分:基本類型變量區、執行環境上下文、操作指令區(存放操作指令)。 4.由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等. 

 

靜態區/方法區:

1.方法區又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量。 2.方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。
3.靜態常量存放在方法區的常量區中,靜態常量初始化后不可更改。

 

 

附:

堆和棧是程序運行的關鍵,應該將其理解清楚。

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

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

為什么要把堆和棧區分出來呢?棧中不是也可以存儲數據嗎?

第一,從軟件設計的角度看,棧代表了處理邏輯,而堆代表了數據。這樣分開,使得處理邏輯更為清晰。分而治之的思想。這種隔離、模塊化的思想在軟件設計的方方面面都有體現。
第二,堆與棧的分離,使得堆中的內容可以被多個棧共享(也可以理解為多個線程訪問同一個對象)。這種共享的收益是很多的。一方面這種共享提供了一種有效的數據交互方式(如:共享內存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節省了空間。
第三,棧因為運行時的需要,比如保存系統運行的上下文,需要進行地址段的划分。由於棧只能向上增長,因此就會限制住棧存儲內容的能力。而堆不同,堆中的對象是可以根據需要動態增長的,因此棧和堆的拆分,使得動態增長成為可能,相應棧中只需記錄堆中的一個地址即可。
第四,面向對象就是堆和棧的完美結合。其實,面向對象方式的程序與以前結構化的程序在執行上沒有任何區別。但是,面向對象的引入,使得對待問題的思考方式發生了改變,而更接近於自然方式的思考。當我們把對象拆開,你會發現,對象的屬性其實就是數據,存放在堆中;而對象的行為(方法),就是運行邏輯,放在棧中。我們在編寫對象的時候,其實即編寫了數據結構,也編寫的處理數據的邏輯。不得不承認,面向對象的設計,確實很美。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM