2013-06-25 81 views
8

當jvm(我的例子中的熱點)永久性地將某些代碼路徑編譯成機器代碼時,機器代碼被存儲在哪裏?在進程內存的.text段中?在過程的堆?當java jvm編譯字節碼時,代碼在哪裏進入進程空間?

我不是在談論JITing。根據我的理解,JIT將編譯並運行字節碼,而無需將編譯後的代碼保存在任何地方。但是什麼時候jvm 保存代碼 - 哪裏在進程空間它保存它? ......正如評論和答案指出的那樣,我所要求的一切其實都是JIT的一部分。

編輯:

按我下面的評論,我特別提到在這裏是爲「自適應優化」的情況:http://www.oracle.com/technetwork/java/whitepaper-135217.html#hotspot

+2

JVM何時產生JITing期間以外的編譯代碼? – selig

+1

JVM不會永久性地將字節碼編譯爲本機機器碼。因此它不會永久存儲在任何地方。 –

+0

@AlexanderBird:那就是_is_ JITting。 –

回答

3

首先,你所描述的是JIT - 特別是如何在熱點

作品要獲得關於其中的代碼在運行時保存問題 - 這是在這個過程中堆和指針在對象的克拉斯文件的方法代碼更新爲指向它。還有一種叫做OSR(堆棧替換)的東西,用於直接在堆棧上編譯長時間運行的循環。

+0

謝謝你回答我的問題和解密我想問的問題:) –

+0

編譯後的代碼是否存儲在與[此問題]相同的「代碼緩存」中(http://stackoverflow.com/questions/7513185/what -is-reservedcodecachesize)談到?如果是這樣,如果我增加-Xmx,是否會影響代碼緩存? –

+0

是的,我認爲最好使用本文中提到的顯式選項,即'-XX:ReservedCodeCacheSize' – selig

3

我沒有與生產質量的虛擬機一起工作,但這裏是我的五美分。在Unix的可執行

.text部分屬於文件,其存儲可執行代碼;在運行時,這個文件部分被映射到系統鏈接器在程序初始化時分配的內存區域,這就是全部(在Linux上,您可以在/proc/$PID/maps的內存中看到內存中的部分佈局)。

至於類Unix系統上的JIT編譯,我只能想到mmap system call分配的內存區域,啓用了PROT_EXEC標誌。此調用由POSIX標準指定,並由Linux的系統鏈接程序ld.so用於將任何本機可執行文件加載到內存中。這個調用可以同樣用於在運行時分配新的可執行內存區域。

通常堆通常由OS/MMU從正在執行受保護的,因爲任何/proc/$PID/maps文件表明:

00dd4000-01292000 rw-p 00000000 00:00 0     [heap] 

這裏rw-p意味着在[heap]沒有數據可被執行(儘管,例如,它是不在沒有PAE的32位x86 CPU的情況下,它們沒有硬件功能來防止將一些內存數據作爲代碼運行),但是可以被讀取/寫入。

因此,虛擬機需要一個具有代碼執行權限的專用內存區域。事實上,讓我們來看看對rwx內存區域中一些Java進程的內存佈局:

# cat /proc/12929/maps | grep rwx  # I run a Java VM with PID 12929 
f3700000-f3940000 rwxp 00000000 00:00 0 # - an unnamed executable & writable region 

隨後的本機代碼執行是組裝JIT編譯的本地代碼任一位置,獨立的問題(如共享對象的代碼被編譯,與gcc選項-fPIC)或使用由mmap()返回的地址。

相關問題