Tôi chưa từng làm việc với máy ảo chất lượng sản xuất, nhưng đây là năm xu của tôi.
.text
phần trong tệp thực thi Unix thuộc về tệp lưu trữ mã thực thi; tại thời gian chạy, phần tệp này được ánh xạ tới vùng bộ nhớ được chỉ định bởi trình liên kết hệ thống trong khi khởi tạo chương trình, đó là tất cả (trên Linux, bạn có thể xem bố cục phần trong bộ nhớ trong /proc/$PID/maps
).
Đối với việc biên dịch JIT trên các hệ thống giống Unix, tôi chỉ có thể nghĩ về các vùng bộ nhớ đã được cấp phát bởi mmap
system call khi bật cờ PROT_EXEC
. Cuộc gọi này được chỉ định bởi các tiêu chuẩn POSIX và được sử dụng bởi trình liên kết hệ thống của Linux, ld.so
, để tải bất kỳ tệp thi hành gốc nào vào bộ nhớ. Cuộc gọi này có thể được sử dụng như nhau để phân bổ các vùng bộ nhớ thực thi mới trong thời gian chạy.
Các đống thông thường thường được bảo vệ bởi hệ điều hành/MMU từ được thực thi, như tập tin bất kỳ /proc/$PID/maps
gợi ý:
00dd4000-01292000 rw-p 00000000 00:00 0 [heap]
đây rw-p
có nghĩa là không có dữ liệu trong [heap]
thể được thực hiện (mặc dù, ví dụ, nó không phải là trường hợp với CPU 32 bit x86 không có PAE, chúng không có khả năng phần cứng để ngăn chặn chạy một số dữ liệu bộ nhớ dưới dạng mã), nhưng có thể đọc/ghi.
Vì vậy, VM cần một vùng bộ nhớ chuyên dụng với quyền thực thi mã. Thật vậy, chúng ta hãy tìm kiếm rwx
khu vực bộ nhớ trong một số bố trí java bộ nhớ quá trình:
# 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
Sau đó thực hiện các mã gốc là một vấn đề lắp ráp mã gốc JIT biên soạn hoặc vị trí-một cách độc lập (như đối tượng chia sẻ mã được biên soạn, với gcc
tùy chọn -fPIC
) hoặc sử dụng địa chỉ được trả về mmap()
.
Nguồn
2013-09-24 12:58:10
Khi nào JVM tạo mã được biên dịch khác với trong JIT? – selig
JVM không biên dịch vĩnh viễn sang bytecode thành mã máy gốc. Do đó nó không được lưu trữ vĩnh viễn ở bất cứ đâu. –
@ AlexanderBird: Đó là _is_ JITting. –