2010-03-24 59 views
12

Tôi biết Microsoft .NET sử dụng CLR như một trình biên dịch JIT trong khi Java có Hotspot. Sự khác nhau giữa chúng là gì?Sự khác biệt trong JIT giữa Java và .Net

+2

Sự khác biệt về mặt ...? – medopal

+1

NGen được sử dụng để biên dịch MSIL thành mã gốc và làm như vậy cho toàn bộ assembly, tuy nhiên khi không có mã NGen, trình biên dịch JIT trong .Net CLR sẽ thực hiện điều đó một cách nhanh chóng cho bạn. Một so sánh giữa hai sẽ được thực hiện tốt hơn với trình biên dịch JIT trong CLR và không phải với NGen vs Hotspot. – saret

Trả lời

22

Chúng là những con thú rất khác nhau. Như mọi người đã chỉ ra, CLR biên dịch thành mã máy trước khi nó thực hiện một mẩu MSIL. Điều này cho phép nó ngoài việc loại bỏ mã chết điển hình và nội tuyến hóa các tối ưu hóa riêng để tận dụng lợi thế của kiến ​​trúc CPU cụ thể của máy đích (mặc dù tôi không chắc liệu nó có làm được). Điều này cũng gây ra một hit cho mỗi lớp (mặc dù trình biên dịch khá nhanh và nhiều thư viện nền tảng chỉ là một lớp mỏng trên API Win32).

Máy chủ HotSpot đang thực hiện một cách tiếp cận khác. Nó quy định rằng hầu hết các mã được thực hiện hiếm khi, do đó nó không có giá trị để dành thời gian biên dịch nó. Tất cả bytecode bắt đầu ở chế độ diễn giải. VM giữ số liệu thống kê tại các trang gọi và cố gắng xác định các phương thức được gọi nhiều hơn số lần được xác định trước. Sau đó, nó biên dịch chỉ những phương thức này với trình biên dịch JIT nhanh (C1) và hoán đổi phương thức trong khi nó đang chạy (đó là nước sốt đặc biệt của HS). Sau khi phương thức biên dịch C1 đã được gọi một số lần nữa, cùng một phương thức được biên dịch với trình biên dịch chậm, nhưng phức tạp và mã được hoán đổi lại một cách nhanh chóng.

Vì HotSpot có thể trao đổi phương thức trong khi chúng đang chạy, trình biên dịch VM có thể thực hiện một số tối ưu hóa đầu cơ không an toàn trong mã được biên dịch tĩnh. Một ví dụ kinh điển là công văn tĩnh/nội tuyến của các cuộc gọi đơn hình (phương pháp đa hình chỉ với một thực hiện). Điều này được thực hiện nếu VM thấy rằng phương thức này luôn luôn giải quyết cho cùng một đích. Những gì được sử dụng để được gọi phức tạp được giảm xuống một vài bảo vệ hướng dẫn CPU, được dự đoán và pipelined bởi CPU hiện đại. Khi điều kiện bảo vệ dừng đúng, VM có thể lấy một đường dẫn mã khác hoặc thậm chí thả trở lại chế độ diễn giải. Dựa trên số liệu thống kê và khối lượng công việc của chương trình, mã máy được tạo có thể khác nhau ở các thời điểm khác nhau. Nhiều người trong số các tối ưu hóa dựa vào thông tin thu thập được trong quá trình thực hiện chương trình và không thể nếu bạn biên dịch một lần khi bạn tải lớp.

Đây là lý do tại sao bạn cần khởi động JVM và mô phỏng khối lượng công việc thực tế khi thuật toán điểm chuẩn (dữ liệu bị lệch có thể dẫn đến việc không thực hiện các tối ưu hóa). Các tối ưu hóa khác là cắt bỏ khóa, khóa xoay thích ứng, phân tích thoát và phân bổ ngăn xếp, v.v.

Điều đó nói rằng, HotSpot chỉ là một trong các máy ảo. JRockit, Azul, J9 của IBM và RVM có thể đặt lại, - tất cả đều có các cấu hình hiệu suất khác nhau.

+0

Xem thêm http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html – ddimitrov

+0

Có đúng là đối với Java "tất cả bytecode bắt đầu ở chế độ diễn giải" không? Tôi nghĩ rằng có một số cuộc gọi được thực hiện lúc khởi động quá và nếu nó vượt quá ngưỡng họ sẽ được biên dịch lúc khởi động. Điều này có thể phụ thuộc vào trình biên dịch: https://www.ibm.com/support/knowledgecenter/en/SSYKE2_8.0.0/com.ibm.java.lnx.80.doc/diag/understanding/jit_overview.html – swdon

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