簡體   English   中英

在Java中,可變內存空間是動態分配還是靜態分配?

[英]in Java is variable memory space allocated dynamically or statically?

如果我們運行這一行代碼

long num = 5;

這個變量有64位空間嗎? 還是大小取決於旁邊的值? 從邏輯上講,它應為64位,因為原始數據類型是可變的。 但是我的結論是真的嗎?

此外,如果我們有一個不變的對象,例如字符串

String str = "Hello World";

默認情況下,將此字符串賦予最大內存似乎很不直觀。 如果要設置一個String然后進行更改,則只需將指針更改為第二個String(新創建的String)的內存地址即可。

有人可以回答這個問題或為我指出正確的方向嗎?

long是一個64-bit原始值,無論您保留的是什么實際值。

String是包裝char[] 內部數組的大小取決於內部字符的數量。 每個char 16-bits ¹。

¹比這復雜一點,但通常來說,每個字符16位。

根據JLS§4.2§4.2.1

整數類型為byte,short,int和long,其值分別為8位,16位,32位和64位有符號的二進制補碼整數,以及char,其值為16位無符號整數。代表UTF-16代碼單元(第3.1節)。

浮點類型為浮點型,其值包括32位IEEE 754浮點數;以及雙精度型,其值包括64位IEEE 754浮點數。

顯然,為了使這些原語能夠具有最小值和最大值,它們需要用固定數量的內存表示,因此它不能可變。

關於String ,每個對象都有一個char[] (直到JDK 9)支持,該char[]具有固定的長度。

有不同種類的變量,因此,沒有一個答案。

堆變量(也稱為字段 )通常具有與數據類型匹配的大小,有時甚至更多,具體取決於對齊方式,但始終足以容納數據類型的任何有效值。 就像您自己已經提到的那樣, 引用類型指向堆內存中的一個對象,然后為另一個對象分配引用只會更改地址,因此引用類型的變量具有固定大小,能夠存儲堆內存地址¹,無論引用對象的大小。 由於String實例是不可變的,因此重新分配是更改String變量的唯一方法。

對於局部變量,情況有所不同。 在這里,處理速度比減少內存消耗更為重要。 因此,數據類型booleanbyteshortcharint都統一視為int ,您已經在源代碼級別上注意到了,因為在這些數據類型上進行的所有算術運算( boolean除外)都得出int 這種轉換已經在編譯時發生。 在運行時優化代碼時,JVM可以重新建立較小的存儲類型,但這不是通常的方向。 局部變量更有可能映射到CPU寄存器,而根本沒有任何存儲空間。 或者,如果將寄存器計為存儲,則它們的寬度至少為32位,而在當今大多數系統中為64位。

保持你的long num = 5; 例如,像HotSpot這樣的JVM使用諸如靜態單分配形式這樣的優化,它允許將num后續讀取視為使用常量5 ,因此由於其實際值,它們可以將其視為int ,但是通常,效果是用可預測的結果代替計算,從而根本不需要存儲值。


¹堆的大小不必與理論上可尋址的內存一樣大,因此具有CompressedOOP的 JVM僅在32位架構上使用32位作為對象引用,只要堆小於對齊 ×2³²,即默認值為32GiB對准。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM