Java 壓縮指針

現在基本上已經是 64 位機的時代了,內存單元的地址也是 64 位。

在 Java 中,除了 8 種基本類型,最常見的類型就是引用類型了,引用類型封裝了引用對象的指針。使用壓縮指針將 64 位長度的指針壓縮到 32 位,可以有效降低存儲空間的開銷。

壓縮指針

首先它不是一個地址,它是一個相對於堆 64 位基址上的一個偏移量。由於對象大小一定是 8 字節的整數倍,所以這個偏移量的單位不是字節,而是 8 字節。

CompressedOops 轉換成地址:ObjectAddress64 = BaseAddress64 + 8*CompressedOops。

注:oops 是 Ordinary Object Pointers 的縮寫。

CompressedOops 偏移量的單位如果是字節,尋址範圍是 4 GB,那麼實際上的尋址範圍爲 32 GB。(RAM 存儲器的編址以字節爲單位。)

所以如果堆大小大於 32 GB,壓縮指針就不能用了,只能老老實實的使用 64 位的指針。

Java SE 6u23 和更高版本默認情況下支持並啓用壓縮指針。在 Java SE 7 中,對於未設置 -Xmx 參數或 -Xmx 設置小於 32 GB 的 64 位 JVM 進程中,默認使用壓縮指針。對於在 6u23 發行版之前的 JDK 6,使用 -XX:+UseCompressedOops 啓用壓縮指針。

零基壓縮指針

JVM 進程可以請求操作系統把堆的基址分配在虛地址爲 0 的位置,那麼 CompressedOops 轉換成地址,就成了:ObjectAddress64 = 8*CompressedOops,少了一個加法操作。

如果堆大小小於 4 GB,還可以去掉 8 的縮放,再少一個乘法操作。壓縮指針直接取 64 位地址的低 32 位即可。

官方文檔裏說:對於大小約爲 26g 的 Java 堆,任何 Solaris、Linux 和 Windows 操作系統通常都能夠在虛擬地址 0 處分配 Java 堆。

官方文檔鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章