使用ByteBuffer就是一個例子;將數據從Array和HeapByteBuffer複製到DirectByteBuffer中執行JNI調用。如果允許JVM在垃圾收集期間移動堆內存,那麼由於移動指針,垃圾收集不會導致JNI爆炸?
基本上這...
public static void copyFromByteArray(byte[] src, long srcPos, long dstAddr, long length)
{
long offset = arrayBaseOffset + srcPos;
while (length > 0)
{
long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
unsafe.copyMemory(src, offset, null, dstAddr, size);
length -= size;
offset += size;
dstAddr += size;
}
}
它採用直接堆計算堆指針和複製的神奇。如果這個指針可能在這個例程的中間變得無效,那麼這甚至是遠程安全的?
對於那些關注:UNSAFE_COPY_THRESHOLD爲1GB
編輯:感謝您的答覆。我爲任何正在尋找相同問題答案的人添加以下參考。這個過程使用安全點(我不知道他們叫什麼,所以我不能只是谷歌它)。
參考文獻:
- http://blog.ragozin.info/2012/10/safepoints-in-hotspot-jvm.html
- http://chriskirk.blogspot.com/2013/09/what-is-java-safepoint.html
unsafe.copyMemory是一個JNI調用。 C代碼不安全並且無鎖。它通過將對象轉換爲(uintptr_t)並直接從本地內存地址進行復制來工作。 這是否意味着所有JNI命令=不安全狀態?我試圖更好地理解我可以逃避的事情。 – bond
不回答問題。你可以強制一個JNI方法進入你喜歡的所有安全點,但它仍然會有直接的對象指針,其值不變。這個答案沒有認同正確的機制。 – EJP