2012-10-25 49 views
8

Java虛擬機也可以使用int大小的short字段(這取決於它們的內部實現)。只有陣列(short[])是例外情況,它總是保證它們在內部佔用的空間少於int[])。那麼DalvikDalvik中「短」字段需要的內存?

E.g.我有一個包含50個字段short的類。有時在我的應用程序中,存在10000個這樣的類。這意味着short字段應該使用1MB的內存,但如果 Dalvik在內部使用4字節的short值,那麼這將是2MB的內存使用量。

Dalvik應該使用多少內存? (這是指其內部存儲器的使用,並且我意識到它可能不會被系統內存使用所反映的事實,例如,因爲Dalvik已經從系統中預留了更高的內存量。)

+1

給準備(格式)編輯我的文章的用戶:謝謝。不幸的是,該系統沒有讓我接受它,它說「編輯已被拒絕」。所以,據我所知,我試圖自己實施編輯。 –

+0

「Java虛擬機對於短字段使用int大小的寬度也是衆所周知的」,您可以使用任何引用來備份此語句嗎? – kosa

+0

我在那裏有點不準確,所以我編輯了它。這裏有一些相關的stackoverflow主題:http://stackoverflow.com/questions/8855754/android-does-short-take-really-2-bytes http://stackoverflow.com/questions/1904857/which-is-better- to-use-short-or-int –

回答

4

在dalvik中,double和long字段是8個字節,其他所有內容(包括short)都是4個字節。

另一方面,短數組每個元素需要2個字節(除了數組+對象簿記的前期空間外)。

陣列

new-array操作碼調用dvmAllocArrayByClass(線71)到分配空間。然後調用dvmAllocPrimitiveArray(第113行)。在dvmAllocPrimitiveArray的開關中,'S'情況用於短陣列。你可以看到它調用allocArray(第38行),寬度= 2。

allocArray,它執行以下計算來計算所述陣列的尺寸大小:

size_t elementShift = sizeof(size_t) * CHAR_BIT - 1 - CLZ(elemWidth); 
size_t elementSize = length << elementShift; 
size_t headerSize = OFFSETOF_MEMBER(ArrayObject, contents); 
size_t totalSize = elementSize + headerSize; 

對於短的32位的系統上,該計算將是:

size_t elementShift = (4 * 8) - 1 - 30; //== 1; 
size_t elementSize = length << 1; //i.e. length * 2 
size_t headerSize = <some constant value>; 
size_t totalSize = length*2 + <some constant value>; 

短陣列每個元素需要2個字節。

字段

new-instance操作碼調用dvmAllocObject(線181),以供新對象分配空間。分配的大小基於字段ClassObjectobjectSize設置在computeFieldOffsets(3543行)。如果您發現fieldOffset在此函數中增加的每個實例,您會注意到它總是以4個字節爲單位遞增。

短字段需要4個字節。

+0

這正是我所尋找的分析答案的類型。謝謝! –

2

(會但它太長了。)

由於JVM在概念上是一臺帶有4字節寄存器的機器,所有4字節字段都用於「短」本地變量堆棧框架中的其他垃圾沒有太大區別。

舉例來說,它可能取決於節省存儲的折衷,而不得不花費週期來擴大和對齊 - 擴展往往需要一個小的週期,甚至是在邊界對齊方面據稱是「不可知論的」架構對於境外訪問通常會有一定的代價,所以如果沒有首先重新排列它們來維護字/雙字邊界,那麼「打包」字段可能會降低性能。

所以如果JVM選擇「打包」字段重新安排通常是必需的。樸素的JVM將避免重新排列,因爲這會讓JVM的幾個方面變得更簡單,但是(在一個例子中)在AS/400上,我們發現積極重新排序和打包實例字段對於渴求存儲的應用程序性能提高了30%。

我從來沒有看過Dalvik的內臟。標準的Sun派生的JVM在歷史上(近期沒有看到任何東西)依賴於.class文件中事物的佈局/順序,因此不會「自然地」服從重新排序。但Dalvik重新構成.class文件,因此處於更好的位置來執行實例字段重新排序。

請注意,要測試Dalvik包裝short字段的假設,您必須創建一個包含幾十個實例字段的類,並確定產生的對象大小是多少。另外(假設在第一種情況下看到包裝),創建一個與shortint(或可能是long)字段交叉的類別,以查看Dalvik是否對它們重新排序以實現打包。