我沒有與生產質量的虛擬機一起工作,但這裏是我的五美分。在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()
返回的地址。
JVM何時產生JITing期間以外的編譯代碼? – selig
JVM不會永久性地將字節碼編譯爲本機機器碼。因此它不會永久存儲在任何地方。 –
@AlexanderBird:那就是_is_ JITting。 –