2013-06-25 44 views
8

Khi jvm (điểm phát sóng trong trường hợp của tôi) biên dịch vĩnh viễn một số đường dẫn mã nhất định vào mã máy, mã máy đang được lưu trữ ở đâu? trong phân đoạn .text của bộ nhớ quá trình? trong đống của quá trình ??khi java jvm biên dịch bytecode, mã đó đi đâu trong không gian quá trình?

Tôi không nói về JITing. Từ sự hiểu biết của tôi, JIT sẽ biên dịch và chạy bytecode mà không bao giờ lưu mã được biên dịch ở bất cứ đâu. Nhưng những gì về khi jvm lưu mã đó - nơi nào trong không gian quá trình hiện nó lưu nó? ... như các ý kiến ​​và câu trả lời chỉ ra, tất cả mọi thứ tôi đã yêu cầu là, trên thực tế, một phần của JIT.

EDIT:

theo nhận xét của tôi dưới đây, tình hình Tôi đặc biệt đề cập đến là tài liệu ở đây là "tối ưu hóa thích nghi": http://www.oracle.com/technetwork/java/whitepaper-135217.html#hotspot

+2

Khi nào JVM tạo mã được biên dịch khác với trong JIT? – selig

+1

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. –

+0

@ AlexanderBird: Đó là _is_ JITting. –

Trả lời

3

Thứ nhất, những gì bạn đang mô tả là JIT - cụ thể nó như thế nào hoạt động trong Hotspot

Để trả lời câu hỏi của bạn về nơi mã được lưu khi chạy - nó nằm trong quy trình và con trỏ tới mã phương thức trong tệp Klass của đối tượng được cập nhật để trỏ tới nó. Ngoài ra còn có một cái gì đó gọi là OSR (trên thay thế ngăn xếp) để biên dịch các vòng chạy dài trực tiếp trên ngăn xếp.

+0

Cảm ơn bạn đã trả lời câu hỏi của tôi và giải mã những gì tôi đang cố hỏi :) –

+0

Mã được biên dịch được lưu trữ trong cùng một "bộ nhớ cache mã" mà [câu hỏi này] (http://stackoverflow.com/questions/7513185/what -is-reservedcodecachesize) nói về? Nếu vậy, nếu tôi tăng -Xmx, điều đó có ảnh hưởng đến bộ đệm mã không? –

+0

Có và tôi nghĩ tốt nhất nên sử dụng tùy chọn rõ ràng được đề cập trong bài đăng này, tức là '-XX: ReservedCodeCacheSize' – selig

3

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().

Các vấn đề liên quan