java中的堆棧 如何準確理解Java中的堆與棧?
如何準確理解Java中的堆與棧?謝謝!Java運行時數(shù)據(jù)區(qū)有Java虛擬機棧和本地方法棧,用于執(zhí)行方法;堆用于存儲對象實例和數(shù)組。Java虛擬機堆棧執(zhí)行每個Java方法時,將創(chuàng)建一個堆??蚣堋6褩?/p>
如何準確理解Java中的堆與棧?
謝謝
!Java運行時數(shù)據(jù)區(qū)有Java虛擬機棧和本地方法棧,用于執(zhí)行方法;堆用于存儲對象實例和數(shù)組。
Java虛擬機堆棧
執(zhí)行每個Java方法時,將創(chuàng)建一個堆??蚣?。堆棧幀用于存儲局部變量列表、操作數(shù)堆棧、動態(tài)鏈表和方法出口等信息。每個Java方法從調(diào)用開始到執(zhí)行完成的過程,對應于Java虛擬機棧中棧幀從棧入口到棧出口的過程。根據(jù)Java虛擬機規(guī)范,如果線程請求的深度大于虛擬機允許的深度,則拋出StackOverflowerError異常;如果虛擬機可以動態(tài)擴展,但擴展過程中內(nèi)存不足,則拋出outofmemoryerror異常。Java虛擬機棧的生命周期遵循線程,是線程的私有生命周期。
Local method stack
Java虛擬機堆棧用于執(zhí)行Java方法,而本地方法堆棧用于執(zhí)行本地方法。它的功能類似于Java虛擬機堆棧,還拋出StackOverflowerError異常和outofmemoryerror異常。本地方法堆棧的生存期也是線程跟隨和線程私有的。
Heap
堆是Java虛擬機中最大的內(nèi)存空間?;旧?,所有對象實例和數(shù)組都在這里分配內(nèi)存空間,這是所有線程共享的。在Java虛擬機規(guī)范中,堆可以位于物理上不連續(xù)的內(nèi)存空間中,只要它在邏輯上是連續(xù)的。當堆中沒有足夠的內(nèi)存分配并且此時無法擴展時,將拋出outofmemoryerror異常。
為什么說java里面只有值傳遞?
在這個問題上,不同的人有不同的理解。對于Java初學者來說,他們可能認為Java中的參數(shù)傳遞分為值傳遞和引用傳遞。至于為什么,教科書上說了。對于程序員的某些工作年限,他們可能會認為,如果傳遞的參數(shù)類型是普通類型,則傳遞的是值;如果參數(shù)是對象,則傳遞的是引用。另一些人認為,只有Java中的值傳遞才是主要問題的主題。
對于Java編程語言,前兩種理解是錯誤的。Java中只使用值傳遞。對我來說,一開始,我也理解了價值傳遞和參照傳遞的理論,但隨著自己代碼的積累,我逐漸發(fā)現(xiàn)事實并非如此。那么為什么只有價值傳遞呢?
首先,讓我們了解什么是值傳遞,什么是引用傳遞?
值傳輸意味著調(diào)用函數(shù)時,實際參數(shù)值被復制并傳遞給被調(diào)用函數(shù)。修改被調(diào)用函數(shù)中的參數(shù)值不會影響原始參數(shù)值。
引用傳遞意味著調(diào)用函數(shù)時,實際參數(shù)的地址直接傳遞給被調(diào)用函數(shù)。修改被調(diào)用函數(shù)中的參數(shù)值將影響原始參數(shù)值。
如果傳遞的參數(shù)類型是普通基本類型,則必須復制實際參數(shù)值并將其傳遞給形式參數(shù)。但是,當參數(shù)類型是對象時,它也是復制的參數(shù)值,并將其傳遞給形式參數(shù)。只復制對象的引用地址,即內(nèi)存中分配的存儲地址,而不是直接傳遞的引用地址。
此時,有些人可能會問為什么一個對象會被傳遞給另一個方法。在此方法中修改對象的屬性值時,原始調(diào)用方法中對象的屬性值將更改。這不就是參考傳遞嗎?
事實上,這是一個非常令人困惑的問題。如果你仔細看看上面的說法,事實并非如此。將一個對象傳遞給另一個方法會傳遞什么?傳遞對象引用的地址。對象引用的地址是否已在其他方法中修改?原始對象引用是否受影響?不
!因此,Java中沒有引用傳遞,只有值傳遞。不要犯任何錯誤
String存放在堆中還是棧中?
有問題的字符串應該是指Java中的字符串。這里的答案是Java。
字符串是一個不可變的對象,在Java中只能用作常量。Java代碼中的所有顯式字符串,即直接編寫的字符串,如“ABC”,都是字符串對象。字符串本身作為一個對象,必須在堆上,而字符串的內(nèi)容char[]value則放在堆常量區(qū)域的一個特殊區(qū)域中。
所以字符串本身就是放在堆上的,根據(jù)垃圾收集的情況,它可以分為新一代和老一代。如果字符串對象剛剛創(chuàng)建,它通常位于新一代堆中。如果已經(jīng)創(chuàng)建了很長時間,很可能是在舊堆時代。請注意,字符串中的字符串內(nèi)容(即字符數(shù)組值)位于堆的常量區(qū)域中。如果首先有一個字符數(shù)組,例如char[]arr{“a”、“b”、“c”},然后調(diào)用String s=new String(arr)來創(chuàng)建該字符串,那么字符數(shù)組就不再位于常量區(qū)域,而是與堆上的其他對象類似。請注意,即使在堆棧上分配了ARR數(shù)組,以這種方式創(chuàng)建的字符串中的值仍在堆上。如果你想把這個字符串放在常量區(qū)域,你可以調(diào)用String.實習生.
堆棧上沒有對象,只有基本變量和引用變量,因此字符串只能在堆上,而不能在堆棧上。