映射相同的內存(在POSIX mmap
作爲伊格納西奧提到,MapViewOfFile
在Windows上)到多個虛擬地址可以提供你一些有趣的一致性難題(當在另一地址讀取是在一個地址可見寫?)。或者可能不是。我不確定所有的平臺保證是什麼。
更普遍的是,只需在指針中保留幾位並根據需要進行移動。
如果所有對象都對齊到8字節的邊界,通常只需將標記存儲在指針的3個最低有效位中,並在解引用之前屏蔽它們(如提到的那樣)。如果您選擇更高的對齊方式,例如16字節或32字節,則可以使用3或5個最低有效位進行標記。等同地,選擇幾個最重要的位進行標記,並在解除引用之前關閉它們。 (包裝指針到IEEE-754浮點數(2個23個值)或雙打(2個51個值)的信號NaN時有時不連續的比特被使用,例如。)
繼續在高端的指針,x86-64的當前實現在64位指針(0x0000000000000000-0x00007fffffffffff + 0xffff800000000000-0xffffffffffffffff)中最多使用48位,並且Linux和Windows僅將用戶空間的第一範圍中的地址分發給用戶空間,有效位可以被安全地屏蔽掉。 (雖然這不是可移植的也不保證在將來保持真實。)
另一種方法是停止考慮「指針」,並簡單地將索引用於更大的內存數組,因爲JVM使用-XX:+UseCompressedOops
。如果您已經分配了一個512MB池並存儲了8字節對齊的對象,則可能有對象位置,因此除索引外,32值還有6位可用。解引用將需要將索引乘以對齊到數組的基址,並保存在別處(每個「指針」都是一樣的)。如果你仔細看看,這只是對先前技術的總結(它總是以0爲基礎,其中事物與真實指針對齊)。