2015-01-24 22 views
7

Vì vậy, tôi đã phương pháp này, viết bằng Java:Mã biên dịch JIT ở đâu?

public void myMethod(int y){ 
    int x = 5 + y; 
    doSomething(x); 
} 

Và giả ứng dụng của tôi gọi điều này là rất nhiều lần ..

Khi chạy mã biên dịch cho phương pháp này trên Java Virtual Machine, JVM sẽ đầu tiên giải thích phương thức. Sau đó, sau một thời gian, nó sẽ quyết định biên dịch nó sang ngôn ngữ máy nếu tôi hiểu chính xác.

Tại thời điểm này,

Nó có bị ghi đè bằng mã máy trong bộ nhớ không? Nếu nó bị ghi đè, vấn đề về sự khác biệt về kích thước sẽ được giải quyết như thế nào? Nếu nó được ghi vào một số nơi khác trong bộ nhớ, thì bytecode có được nạp vào bộ nhớ giải phóng hay không? Và cũng có thể, nếu cả mã byte bytecode và mã jit được biên dịch nằm trong bộ nhớ, khi ứng dụng lần lượt truy cập phương thức này, thì JVM quyết định thực thi mã được biên dịch jit thay vì mã byte như thế nào?

+0

Tôi có ý tưởng rằng loại điều này sẽ phụ thuộc vào việc bạn đang chạy trên máy tính Windows hay, giả sử, trên bộ vi điều khiển RAM bị đói. Nói cách khác, phụ thuộc vào nền tảng, phải không? – Ghostkeeper

+2

Trả lời 1: Tại sao bạn quan tâm? Câu trả lời 2: JVM giữ mã JITCed cho mỗi phương thức trong đống C, liên kết với thông qua các bảng trong biểu diễn bên trong của đối tượng lớp. Mã này chỉ bị xóa khi JVM kết thúc hoặc trong trường hợp hiếm hoi mà lớp đó được "unloaded". Đó là tất cả được quản lý bởi ma thuật phù hợp. –

+1

"Heap" thực sự là một sự nhầm lẫn ở đây - nếu nó đề cập đến bộ nhớ thu được bằng cách sử dụng các cuộc gọi đến malloc (có thể hoặc có thể không được liên kết trang) các trang tương ứng sẽ phải được đánh dấu là thực thi. Nhiều khả năng, JIT phân bổ bộ nhớ cho mã được tạo bằng cách sử dụng mmap, VirtualAlloc và các loại tương tự. –

Trả lời

12

HotSpot JVM có cấu trúc Method trong Metaspace (hoặc PermGen trong các phiên bản trước đó). Nó chứa phương thức bytecode không bao giờ bị ghi đè và a pointer to compiled code, ban đầu NULL cho đến khi phương thức được biên dịch.

Một phương pháp có thể có nhiều điểm vào:

  • _i2i_entry - một con trỏ đến thông dịch bytecode.
  • _code->entry_point() - một điểm vào mã JIT được biên dịch. Các phương thức biên dịch nằm trong CodeCache - vùng đặc biệt của bộ nhớ riêng cho mã được tạo động VM.
  • i2cc2i bộ điều hợp để gọi mã được biên dịch từ trình thông dịch và ngược lại. Các adapter này là cần thiết, bởi vì các phương thức được giải nghĩa và các phương thức được biên dịch có quy ước gọi khác nhau (cách thức các đối số được truyền, cách các khung được xây dựng, v.v.)

Một phương pháp biên dịch có thể có bẫy phổ biến trở lại phiên dịch một số trường hợp hiếm hoi. Hơn nữa, một phương thức Java có thể được biên dịch động nhiều lần, vì vậy JVM không thể vứt bỏ bytecode ban đầu. Không có ý nghĩa để giải phóng nó anyway, bởi vì bytecode thường nhỏ hơn nhiều so với mã biên dịch.

5

Không, nó không bị ghi đè, vì thường không có lợi ích thiết thực nào trong hai lần biểu diễn ở cùng một nơi. Mã bytecode JVM chỉ là một phần dữ liệu. Mã do JIT phát ra là một luồng các lệnh CPU nguyên gốc (trong một số kiến ​​trúc, nó được yêu cầu rằng điều này được đánh dấu rõ ràng là có thể thực thi được). Thông thường, khi một hàm mới được yêu cầu để thực hiện, trình biên dịch JIT đọc mã byte của hàm đó, cấp phát bộ nhớ ở nơi khác, viết mã gốc tương đương với bộ nhớ đó, sau đó trả về một con trỏ hàm vào mục nhập của mới tạo mã gốc.

+1

Ngoài ra: trên nhiều nền tảng hiện đại, bạn phải yêu cầu rõ ràng bộ nhớ * thực thi * từ hệ thống con bộ nhớ ảo. Không có lý do chính đáng nào để bytecode được cấp phát cho một trang thực thi. –

2

Theo như tôi biết, số The Java® Virtual Machine Specification không chỉ định bất kỳ điều nào trong số đó.
Các tài liệu tham khảo chỉ để JIT Tôi có thể tìm thấy là trong Chapter 3:

[...] Một ví dụ về một phiên dịch như vậy là một just-in-time (JIT) tạo mã, mà tạo ra hướng dẫn nền tảng cụ thể chỉ sau khi mã Java Virtual Machine đã được tải. Chương này không giải quyết các vấn đề liên quan đến việc tạo mã, chỉ những vấn đề liên quan đến việc biên dịch mã nguồn được viết bằng ngôn ngữ lập trình Java sang các hướng dẫn Java Virtual Machine.

Vì vậy, với hiểu biết của tôi, điều này có thể được thực hiện khác nhau bằng cách triển khai khác nhau. Tuy nhiên, đối với tôi, dường như rất ít khả năng bộ nhớ chứa bytecode java bị ghi đè bằng các lệnh CPU gốc, bởi vì các lệnh CPU có thể thực thi về mặt kỹ thuật và bytecode chỉ là dữ liệu, vì nó phải được hiểu. Nó sẽ không thể là mặc dù, chỉ rất kỳ quặc.

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