2015-07-02 40 views
2

.Net, it seems不能可以獲得可以卸載的動態編譯代碼的本機性能?

  1. 動態編譯代碼
  2. 呼叫直接經編譯的代碼(即,W/O 「遠程」,編組等)
  3. 刪除(僅)從編譯的代碼內存

你必須在2.(通過生成代碼到調用AppDomain本身)或3(通過生成代碼到一個可拋棄的AppDomain),但你不能有兩者。

現在我很好奇,如果這是可能的Java。我不知道有足夠的瞭解類加載器,但似乎在Java中,我可以

  1. 動態編譯的代碼放到一個扔掉的類加載器
  2. 調用編譯後的代碼(比如,通過虛擬方法調用預定義接口)直接,W/O任何編組
  3. 撈出來編譯的類和扔掉的類加載器的所有引用,這樣GC會照顧去除

的是這樣的假設是否有效?

回答

2

是的,你可以編譯/加載一個代碼類的類加載器,調用它沒有問題。

是的,動態代碼將達到'完整性能'。沒有區別。但是,新加載的代碼將以解釋模式啓動,需要在編譯之前進行預熱。

但是,第3點非常棘手。

  • '泄漏'扔掉類加載器很容易/可能。類加載器保持對其加載的類的引用。每個類都有一個對它的類加載器的引用。每個對象都是對它的類的引用。因此,只要你有一個對象或類的引用,這些對象或類用加載類拋棄類加載器加載,它和它的加載類就保持活着。 因爲很容易引用一個對象,所以'classloader'泄漏非常普遍。
  • 它取決於GC配置和JVM版本,它實際上是GC在所加載的類上傳遞的。您可能需要額外的標誌來啓用它。類似於CMS GC'-XX:+ CMSClassUnloadingEnabled'。
  • 有一個代碼緩存(在OpenJDK /熱點),它保持編譯的代碼。如果您在應用程序的整個生命週期中持續加載代碼,則可能會超出此緩存。在較舊的JVM中,它只是被填滿了,一旦滿了,它就停止編譯代碼,性能下降,除非你啓用了緩存(-XX:+ UseCodeCacheFlushing)。 Afaik在更新的版本中默認會刷新。仔細檢查一下。您可能需要關注代碼緩存。 (通過JMX)
+0

謝謝。顯然,如果你持有一個對象的引用,你不能指望它的類加載器消失。好消息似乎是:在Java中,它可以完成。在.Net中,你必須決定:執行和泄漏 - 或者兩者都不。 –

相關問題