2014-07-14 28 views
13

調用Java方法聲明爲native時,JVM運行時必須執行的常見步驟是什麼?調用本地方法時,JVM必須做什麼?

HotSpot 1.8.0 JVM如何實現JNI函數調用?涉及哪些檢查步驟(例如,返回後的未處理異常?),JVM要執行哪些簿記(例如本地引用註冊表?)以及控制權在調用本地Java方法之後的位置?如果有人能夠提供本地HotSpot 1.8.0代碼的入口點或重要方法,我也會很感激。

聲明:我知道我可以自己閱讀代碼,但事先的解釋有助於快速找到我的代碼。另外,我發現這個問題值得谷歌搜索。 ;)

回答

28

與簡單的C函數調用相比,從Java中調用JNI方法相當昂貴。 熱點通常執行以下大多數步驟來調用JNI方法:

  1. 創建堆棧幀。
  2. 根據ABI將參數移動到正確的寄存器或堆棧位置。
  3. 將對象引用包裝爲JNI句柄。
  4. 獲取用於靜態方法的JNIEnv*jclass並將它們作爲附加參數傳遞。
  5. 檢查是否應該調用method_entry跟蹤功能。
  6. 如果方法是​​,則鎖定對象監視器。
  7. 檢查本地函數是否已鏈接。函數查找和鏈接是懶惰地執行的。
  8. 將線程從in_java切換到in_native狀態。
  9. 調用本機功能
  10. 檢查是否需要安全點。
  11. 將線程返回到in_java狀態。
  12. 如果鎖定,解鎖監視器。
  13. 通知method_exit
  14. 解包對象結果並重置JNI處理塊。
  15. 處理JNI異常。
  16. 刪除堆棧幀。

此過程的源代碼可在SharedRuntime::generate_native_wrapper找到。

正如您所看到的,開銷可能很大。但在許多情況下,上述大多數步驟都不是必需的。例如,如果一個本地方法只是對一個字節數組執行一些編碼/解碼,並且不會拋出任何異常,也不會調用其他的JNI函數。對於這些情況,HotSpot有一個稱爲Critical Natives的非標準(並且未知)約定,討論了here

+0

你遺漏了一些。在調用方法之前固定參數對象並在之後解除固定。彈出推送的任何幀,並在返回後釋放由該方法創建的所有本地引用。 – EJP

+0

@EJP你是什麼意思的固定參數對象?HotSpot不支持常規意義上的對象鎖定。沒有本地參考實際上是「發佈」。 JVM通過兩條機器指令(我已經提到過)立即重置整個JNI句柄塊,任何創建的本地JNI參考自動變成垃圾。 – apangin

相關問題