我知道Java使用填充;對象必須是8個字節的倍數。但是,我沒有看到它的目的。它是幹什麼用的?它的主要目的究竟是什麼?爲什麼Java對象必須是8的倍數?
回答
其目的是alignment,它允許以一些空間爲代價加快內存訪問。如果數據未對齊,則處理器需要在加載內存後進行一些轉換才能訪問它。
此外,垃圾回收簡化(並加快)最小分配單元的大小。
Java不需要8字節(64位系統除外),但由於32位體系結構是創建Java時的常態,因此Java標準中可能需要4字節對齊。
我發現話說[百科](http://en.wikipedia.org/wiki/Java_performance#Memory_usage)和[Javamex(http://www.javamex.com/tutorials/memory/object_memory_usage.shtml)此信息它是8個字節。但唯一的目的是垃圾收集? – Nando 2012-08-12 23:00:15
@ user1110725,請仔細閱讀。對齊不僅適用於垃圾收集,還適用於內存訪問。應遵循 – cyroxx 2012-08-12 23:15:54
+1 – 2013-10-08 09:10:11
Java中的數據類型大小是8的位數位(非字節)的倍數,因爲大多數現代處理器中的字長是8位的倍數:16位,32位,64位。以這種方式,可以使對象中的字段適合(「對齊」)一個或多個詞並儘可能地浪費空間,利用底層處理器的指令操作字大小的數據。
不是,字節。除了數組中的小原語外,大多數(所有?)JVM都將其數據對齊至少4個字節的邊界。 – U2EF1 2012-08-12 22:49:37
我不是在談論數據類型,而是對象。我的意思是,我自己的對象。它們總是8個字節的倍數。至少,這是我讀的。我發現[Javamex(http://www.javamex.com/tutorials/memory/object_memory_usage.shtml)這個信息[百科](http://en.wikipedia.org/wiki/Java_performance#Memory_usage)和。 – Nando 2012-08-12 22:58:17
接受的答案是推測(但部分正確)。這是真正的答案。
首先,對於@ U2EF1的榮譽,8字節邊界的好處之一是8字節是大多數處理器的最佳訪問。但是,這個決定還有更多。
如果您有32位引用,則可以尋址最多2^32或4 GB的內存(實際上,儘管您獲得的更少,但更像3.5 GB)。如果您有64位引用,則可以尋址2^64,即內存爲terrabytes。但是,對於64位引用,一切都趨於放緩並佔用更多空間。這是由於處理64位的32位處理器的開銷,以及由於更少的空間和更多垃圾收集而導致所有處理器上的GC循環更多。
因此,創作者採取了一箇中間立場,並決定使用35位參考,這樣可以達到2^35或32 GB的內存,佔用更少的空間,從而獲得與32位參考相同的性能優勢。這是通過讀取一個32位參考並在讀取時將其左移3位來完成的,並且在存儲參考時將其右移3位。這意味着所有對象必須在2^3邊界(8字節)上對齊。這些被稱爲壓縮的普通對象指針或壓縮的oops。
爲什麼不用36位引用來訪問64 GB內存?那麼,這是一個折衷。您需要大量浪費空間來處理16字節的對齊,並且據我所知,絕大多數處理器不會從16字節對齊中獲得速度優勢,而不是8字節對齊。
請注意,JVM不會打擾使用壓縮的oops,除非最大內存設置爲4 GB以上,而默認情況下它不是。實際上,您可以使用-XX:+UsedCompressedOops
標誌啓用它們。
這是在32位虛擬機當天重新提供64位系統上的額外可用內存。據我所知,64位虛擬機沒有限制。 Java性能:權威指南,第8章
來源:Java性能:權威指南,第8章
8字節對齊的決定比壓縮的oops特性要早,也適用於32位JVM,它們不支持超過2GB。你推測「未來的JVM將支持64位引用*」是沒有意義的,因爲所有的64位JVM都支持64位引用。當堆大於32GB或者指定'-XX:-UsedCompressedOops'時,或者使用不具備壓縮的oops功能的較舊的JVM時,會使用它們。 – Holger 2016-06-07 18:19:44
也許措辭不佳,但我的意思是使用_all_ 64位的引用,而不是沒有「存儲在64位值中的引用」。上一次檢查(這是前一段時間),你不能在JVM中使用2^64內存堆。 – 2016-06-08 19:12:39
如果你找到一個支持分配2×4字節的真實系統(硬件+操作系統),我會感到非常驚訝。我想知道,你是否明白,那是多大。但是,您可以使用與底層系統支持的堆一樣大的堆。如果您認爲,您遇到了支持少於操作系統的64位JVM,您必須更具體。 – Holger 2016-06-08 20:04:32
- 1. 爲什麼垂直LED的數量必須是8的倍數?
- 2. 爲什麼投影矩陣必須是雙倍的?
- 3. pyDes解密「數據必須是8字節的倍數」
- 4. 爲什麼鎖定對象必須是隻讀的?
- 5. 爲什麼我必須使用的,而不是「對象」
- 6. 爲什麼一個對象變量必須是一個指針?
- 7. 爲什麼typecript會抱怨對象必須是傳播類型的對象
- 8. 爲什麼紋理必須大小爲兩倍?
- 9. 這是什麼意思? 「錯誤:`rhs`必須是語言對象」
- 10. Java SSL異常 - 「總理大小必須是64的倍數...」
- 11. Java:爲什麼單獨的類必須是私有的
- 12. 參數必須是矩形對象
- 13. 爲什麼UISearchDisplayController必須是類變量?
- 14. ui-router爲什麼父母狀態必須是抽象的
- 15. 爲什麼Java Bean必須是可序列化的?
- 16. 要列出的對象 - >爲什麼我必須創建一個新對象?
- 17. 爲什麼必須拋出對象進行復制初始化?
- 18. 爲什麼沒有布爾必須指向一個對象
- 19. 爲什麼必須使用Set來保存對象?
- 20. 爲什麼DECLARE_DYNAMIC&IMPLEMENT_DYNAMIC對於DYNAMIC_DOWNCAST是必須的?
- 21. 爲什麼不會倍增倍增? (Java)
- 22. Java加密:Java Encription:javax.crypto.IllegalBlockSizeException:使用填充密碼進行解密時,輸入長度必須是8的倍數
- 23. 爲什麼java Math.pow參數加倍?
- 24. 可爲空的對象必須有值?
- 25. 爲什麼Java PrintStream必須重載其print()函數?
- 26. 爲什麼IP分段必須在8個字節
- 27. 爲什麼數據庫名稱必須是靜態的?
- 28. 爲什麼我的參數hitTestObject必須是非空錯誤?
- 29. 什麼是從一組中抽取對象的Java 8方法?
- 30. 必須是變體或對象
這與JVM相關。 – 2012-08-12 22:45:08
我很抱歉沒有注意到,但我正在談論Hotspot JVM。 – Nando 2012-08-12 23:01:24
然後你不知道 - 你只是在某處讀它。 – 2012-08-12 23:02:59