[英]java: How does the memory of a class member allocate?
我們有68個int的大類,22個double成員,還有4個成員。 例如
Class A{
public int i1
public int i2
public int i3
....
public Order order1
public Order order2
...
public double..
}
1:i1,i2,i3的內存在物理上是連續的嗎?
2:對於類A,它存儲指向order1和order 2的指針,還是存儲訂單1和order 2的內容?
還有另一個類B,該類的成員是A的數組,即365A。因此B的內存可能很大。 我擔心的是,如果B的大小太大,我們可能會丟失很多2級緩存,從而降低性能。 我們主要將對i1的值求和,對i2的值求和,對i3的值求和,例如,如果對所有365 A求和i1,那么所有這些365A的i1將不會連續地位於內存中。 因此,我們可能會丟失一些緩存,從而導致性能不佳。
我正在考慮使用類B,但刪除類A,並將A中的所有元素移到B,這樣我們就可以
Class B {
public array_of_i1
public array_of_i2
..
}
這樣,當我計算i1或i2的總和時,所有i1或i2都坐在一起,那么也許我們可以提高性能?
由於課程人數眾多,我想在變更之前尋求您的意見。
它通常是連續的,但是取決於您所使用的JVM。
一種復雜的情況是,虛擬機規范未強制執行Java對象的內存結構中的運行時,這意味着虛擬機提供程序可以根據需要實現它們。 結果是您可以編寫一個類,並且在另一台VM中運行時,該同一個類中的該類實例所占用的內存量可以與該同一個類中的實例占用的內存量不同。
至於具體的布局,
為了節省內存,Sun VM不會按照聲明對象的順序來布置對象的屬性。 而是按照以下順序在內存中組織屬性:
- 雙打和多頭
- 整數和浮點數
- 短褲和短褲
- 布爾值和字節
- 參考資料
(摘自http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html )
他還介紹了如何處理繼承的類。
JLS並未嚴格指定對象的確切大小,因此這在JVM實現之間可能會有所不同(盡管您可以推斷出一些下限 ,即整數必須至少為 32位)。
但是,在Sun的JVM中,整數占32位,雙精度占64位,對象引用占32位( 除非您在64位JVM上運行並且指針壓縮被禁用)。 然后,對象本身具有一個2字的標題,並且整個內存大小與8個字節的倍數對齊。
因此,總體而言,如果我沒有忘記考慮某件事(完全有可能),則此對象應占用8 * ceil((8 + 68 * 4 + 22 * 8 + 4 * 4) / 8)
= 10448個字節,並且如果您在32位計算機上運行。
但是 -如上所述,您不應真正依賴它,因為它沒有在任何地方指定,並且在實現和不同平台上會有所不同。 與使用性能相關的指標一樣,關鍵是編寫干凈的代碼,衡量影響(在這種情況下,使用探查器查看內存使用情況和執行時間),然后根據需要進行優化。
從宏觀角度來看,性能才是真正重要的。 在設計對象模型時擔心二級緩存丟失確實是錯誤的做法。
(而且具有94個字段的類幾乎肯定不是一個干凈的設計,因此您應該考慮對其進行重構...)
首先,在您從事任何工作之前,您是否已對應用程序進行了概要分析? 緩存未命中是否會造成瓶頸?
您對性能有何要求? (注:“越快越好” 心不是要求*)
或者你可以改變使用較小的類結構,保持在一個緊湊的循環運行起來往往會提高緩存命中率(IFF這是你的性能瓶頸)的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.