Trình biên dịch chỉ trong thời gian (JIT) làm gì?


Câu trả lời:


518

Trình biên dịch JIT chạy sau khi chương trình đã khởi động và biên dịch mã (thường là mã byte hoặc một số hướng dẫn VM) một cách nhanh chóng (hoặc chỉ trong thời gian, như cách gọi của nó) thành một dạng thường nhanh hơn, điển hình là nguồn gốc của CPU chủ tập lệnh. Một JIT có quyền truy cập vào thông tin thời gian chạy động trong khi trình biên dịch chuẩn không có và có thể tối ưu hóa tốt hơn như các hàm nội tuyến được sử dụng thường xuyên.

Điều này trái ngược với trình biên dịch truyền thống biên dịch tất cả mã thành ngôn ngữ máy trước đó chương trình được chạy lần đầu tiên.

Để diễn giải, các trình biên dịch thông thường xây dựng toàn bộ chương trình dưới dạng tệp EXE TRƯỚC lần đầu tiên bạn chạy nó. Đối với các chương trình kiểu mới hơn, một hội đồng được tạo bằng mã giả (mã p). Chỉ sau khi bạn thực thi chương trình trên HĐH (ví dụ: bằng cách nhấp đúp vào biểu tượng của nó), trình biên dịch (JIT) sẽ khởi động và tạo mã máy (mã m) mà bộ xử lý dựa trên Intel hoặc bất cứ điều gì sẽ hiểu.


16
Và ngược lại với mã được giải thích, bắt đầu chạy các lệnh bytecode hoặc VM ngay lập tức mà không bị trì hoãn, nhưng sẽ chạy các hướng dẫn chậm hơn ngôn ngữ máy.
Aaron

3
Một JIT thường được sử dụng với mã được dịch để chuyển đổi nó sang ngôn ngữ máy nhưng có, mã được hiểu hoàn toàn (không có bất kỳ JITting nào) là chậm. Ngay cả mã byte Java mà không có JITter cũng rất chậm.
Đánh dấu Cidade

48
Mục tiêu không phải là mã máy, mặc dù. JRuby có trình biên dịch JIT sẽ biên dịch mã nguồn Ruby thành mã byte Java sau một vài lần gọi. Sau đó, sau một vài lời mời khác, trình biên dịch JVM JIT khởi động và biên dịch mã byte thành mã gốc.
Jörg W Mittag

4
Điều đáng chú ý là, như được Jorg ám chỉ, JIT không nhất thiết phải được gọi ngay lập tức. Thông thường, mã sẽ được diễn giải cho đến khi được xác định rằng nó sẽ có giá trị JITting. Vì JITting có thể đưa ra sự chậm trễ, nên có thể KHÔNG JIT một số mã nhanh hơn nếu nó hiếm khi được sử dụng và do đó phản hồi nhanh quan trọng hơn thời gian chạy tổng thể.
Adam Jaskiewicz

3
@ErikReppen: Nếu một máy mới xuất hiện, biên dịch và tối ưu hóa chương trình cho máy mới đó bằng trình biên dịch thông thường sẽ có khả năng mang lại kết quả nhanh hơn JIT. Mặt khác, một JIT được tối ưu hóa cho máy mới đó sẽ có thể tối ưu hóa hiệu suất của mã được xuất bản trước khi máy mới được phát minh .
supercat

255

Ban đầu, một trình biên dịch chịu trách nhiệm biến ngôn ngữ cấp cao (được định nghĩa là cấp cao hơn trình biên dịch) thành mã đối tượng (hướng dẫn máy), sau đó sẽ được liên kết (bởi một trình liên kết) thành một tệp thực thi.

Tại một thời điểm trong quá trình phát triển của các ngôn ngữ, trình biên dịch sẽ biên dịch một ngôn ngữ cấp cao thành mã giả, sau đó sẽ được phiên dịch (bởi một thông dịch viên) để chạy chương trình của bạn. Điều này đã loại bỏ mã đối tượng và các tệp thực thi và cho phép các ngôn ngữ này có thể được chuyển sang nhiều hệ điều hành và nền tảng phần cứng. Pascal (được biên dịch thành P-Code) là một trong những cái đầu tiên; Java và C # là những ví dụ gần đây hơn. Cuối cùng, thuật ngữ P-Code đã được thay thế bằng mã byte, vì hầu hết các hoạt động giả đều dài một byte.

Trình biên dịch Just-In-Time (JIT) là một tính năng của trình thông dịch thời gian chạy, thay vì diễn giải mã byte mỗi khi một phương thức được gọi, sẽ biên dịch mã byte vào các lệnh mã máy của máy đang chạy, sau đó gọi nó mã đối tượng thay thế. Lý tưởng nhất là hiệu quả của việc chạy mã đối tượng sẽ khắc phục sự kém hiệu quả của việc biên dịch lại chương trình mỗi khi nó chạy.


5
Tuy nhiên, cụm từ "trình biên dịch đúng lúc (JIT) này là một tính năng của trình thông dịch thời gian chạy" gây nhầm lẫn; ví dụ - stackoverflow.com/questions/16439512/...
Stephen C

11
Trên thực tế, JIT là một tiện ích bổ sung và bạn vẫn có thể vô hiệu hóa nó bằng cách sử dụng tham số -Xint cho Java, vì vậy đây chỉ là một tính năng.
Craig Trader

3
Tôi không hoàn toàn đồng ý. JIT không phải là sự tiến hóa - nó là sự thay thế của các trình biên dịch cổ điển.
i486

1
JIT là một bước trên con đường tiến hóa từ các công tắc cơ học cứng cáp đến chỉ định tiêu chí tìm kiếm bằng cách nói "OK Google" với điện thoại thông minh của bạn. JIT hiện tại có sẵn như là một phần của Java 7/8 là những bước nhảy vọt vượt ra ngoài những gì đã có trong Java 2 - đó cũng là sự tiến hóa.
Craig Trader

1
@ i486 - Sun / Oracle có (AFAIK) không bao giờ chuyển trình biên dịch cổ điển ("đi trước thời đại") cho Java tạo mã gốc. Thật khó để tranh luận rằng JIT là một sự thay thế ... khi họ cho rằng nó được cho là một sự thay thế không bao giờ được vận chuyển. (Tôi giảm giá trình biên dịch AOT của GCJ vì điều đó không liên quan gì đến Sun / Oracle và nó cũng không phải là một giải pháp hoàn chỉnh. Nó chắc chắn không thể tồn tại được.)
Stephen C

69

JIT-Chỉ trong thời gian từ mà chính nó nói khi cần thiết (theo yêu cầu)

Kịch bản điển hình:

Mã nguồn được chuyển đổi hoàn toàn thành mã máy

Kịch bản JIT:

Mã nguồn sẽ được chuyển đổi thành ngôn ngữ lắp ráp như cấu trúc [cho ex IL (ngôn ngữ trung gian) cho C #, ByteCode cho java].

Mã trung gian được chuyển đổi thành ngôn ngữ máy chỉ khi ứng dụng cần mã yêu cầu chỉ được chuyển đổi thành mã máy.

So sánh JIT và không JIT:

  • Trong JIT, không phải tất cả mã được chuyển đổi thành mã máy trước tiên, một phần mã cần thiết sẽ được chuyển đổi thành mã máy sau đó nếu một phương thức hoặc chức năng được gọi không có trong máy thì nó sẽ được chuyển thành mã máy ... nó sẽ giảm gánh nặng cho CPU.

  • Vì mã máy sẽ được tạo trong thời gian chạy .... trình biên dịch JIT sẽ tạo mã máy được tối ưu hóa để chạy kiến ​​trúc CPU của máy.

Ví dụ về JIT:

  1. Trong Java JIT là trong JVM (Máy ảo Java)
  2. Trong C #, nó nằm trong CLR (Thời gian chạy ngôn ngữ chung)
  3. Trong Android, nó ở dạng DVM (Máy ảo Dalvik) hoặc ART (Android RunTime) trong các phiên bản mới hơn.

7
JIT cung cấp một số lợi thế đặc biệt trong các khung với sự hỗ trợ cho các loại chung chung thực sự; có thể định nghĩa một phương thức chung có khả năng tạo ra một loạt các loại không giới hạn, mỗi loại sẽ yêu cầu mã máy khác nhau, nhưng chỉ có mã tạo JIT cho các loại thực sự được sản xuất. Ngược lại, trong C ++, trình biên dịch tạo mã cho tất cả các loại chương trình sẽ sử dụng.
supercat

6
JVM không mã JIT lần đầu tiên chạy nó. Một vài lần đầu tiên, nó diễn giải mã byte. Sau đó, nếu mã đó chạy đủ thường xuyên, nó có thể quyết định làm phiền JITting nó.
ninjalj

1
Bạn đang nói JIT trong Java là JVM. Tuy nhiên, chúng tôi đã cung cấp mã được biên dịch cho JVM, phải không? Sau đó, nó biên dịch lại ý bạn?
Koray Tugay

@KorayTugay - Chúng tôi cung cấp Bytecodes cho JVM và JVM sẽ chuyển đổi một phần của mã đó thành mã máy theo yêu cầu. Tài nguyên cũng được lưu.
Durai Amuthan.H

1
Trong Java JIT không phải là JVM. Nó chỉ là một phần của nó.
hạnh phúc

25

Như những người khác đã đề cập

JIT là viết tắt của Just-in-Time, có nghĩa là mã được biên dịch khi cần, không phải trước khi chạy.

Chỉ cần thêm một điểm để thảo luận ở trên, JVM duy trì số đếm theo thời gian một hàm được thực thi. Nếu số này vượt quá giới hạn được xác định trước, JIT sẽ biên dịch mã thành ngôn ngữ máy có thể được bộ xử lý thực thi trực tiếp (không giống như trường hợp thông thường trong đó javac biên dịch mã thành mã byte và sau đó java - trình thông dịch sẽ dịch dòng mã byte này theo dòng mã máy và thực thi).

Ngoài ra, lần tới, hàm này được tính cùng mã được biên dịch được thực thi lại không giống như diễn giải thông thường trong đó mã được diễn giải lại theo từng dòng. Điều này làm cho việc thực hiện nhanh hơn.


14

Trình biên dịch JIT chỉ biên dịch mã byte thành mã gốc tương đương ở lần thực hiện đầu tiên. Sau mỗi lần thực hiện liên tiếp, JVM chỉ sử dụng mã gốc đã được biên dịch để tối ưu hóa hiệu năng.

nhập mô tả hình ảnh ở đây

Không có trình biên dịch JIT, trình thông dịch JVM sẽ dịch từng dòng mã byte để làm cho nó xuất hiện như thể một ứng dụng gốc đang được thực thi.

nhập mô tả hình ảnh ở đây

Nguồn


1
Giải thích của tôi về JIT là nó hoạt động như ghi nhớ, trong đó các hàm được sử dụng thường xuyên được 'lưu trữ' và chi phí biên dịch từ mã byte java sang mã phụ thuộc vào ISA bị bỏ qua. Nếu điều này là chính xác, tại sao java không biên dịch hoàn toàn thành mã gốc ngay từ đầu? Điều này sẽ làm giảm bất kỳ kiểu biên dịch thời gian chạy nào và làm cho java trở thành 'bản địa' cho máy?
Michael Choi

12

JIT là viết tắt của Just-in-Time, có nghĩa là mã được biên dịch khi cần, không phải trước khi chạy.

Điều này có lợi vì trình biên dịch có thể tạo mã được tối ưu hóa cho máy cụ thể của bạn. Trình biên dịch tĩnh, giống như trình biên dịch C trung bình của bạn, sẽ biên dịch tất cả mã trên thành mã thực thi trên máy của nhà phát triển. Do đó trình biên dịch sẽ thực hiện tối ưu hóa dựa trên một số giả định. Nó có thể biên dịch chậm hơn và thực hiện nhiều tối ưu hơn vì nó không làm chậm quá trình thực thi chương trình cho người dùng.


Tại sao mã không được biên dịch được lưu trữ ở một nơi nào đó trong máy tính của người dùng để lần sau ứng dụng được chạy, JIT không phải biên dịch lại chúng?
omerfarukdogan

Quan sát tốt. Có thể làm điều này, nhưng liệu nó có thực sự có lợi hay không phụ thuộc vào nền tảng và cách sử dụng ứng dụng. Tối ưu hóa JIT không nhất thiết giống như ngoại tuyến hoặc tối ưu hóa trước thời hạn, vì vậy lợi ích chỉ có thể là "không phải JITting", có thể hoặc không giúp được gì nhiều.
Brian Lyttle

9

Sau khi mã byte (là kiến ​​trúc trung tính) đã được trình biên dịch Java tạo ra, việc thực thi sẽ được xử lý bởi JVM (trong Java). Mã byte sẽ được nạp vào JVM bởi trình tải và sau đó mỗi lệnh byte được diễn giải.

Khi chúng ta cần gọi một phương thức nhiều lần, chúng ta cần diễn giải cùng một mã nhiều lần và điều này có thể mất nhiều thời gian hơn mức cần thiết. Vì vậy, chúng tôi có trình biên dịch JIT (chỉ trong thời gian). Khi byte đã được tải vào JVM (thời gian chạy của nó), toàn bộ mã sẽ được biên dịch thay vì diễn giải, do đó tiết kiệm thời gian.

Trình biên dịch JIT chỉ hoạt động trong thời gian chạy, vì vậy chúng tôi không có bất kỳ đầu ra nhị phân nào.


2
Toàn bộ mã không được biên dịch khi được tải vào JVM, vì có rất ít thông tin (đọc: hướng dẫn) về cách tiến hành biên dịch. Hãy nhớ rằng hiệu suất là mục tiêu cuối cùng. JIT khá chọn lọc: giám sát và lựa chọn các phương pháp phổ biến nhất để tối ưu hóa. Và nó tiếp tục làm điều này cho đến khi đạt được mức tối ưu hóa tối đa cho các phương thức riêng lẻ.
Yaw Boakye

7

Just In Time Compiler (JIT):
Nó biên dịch mã byte java thành các lệnh máy của CPU cụ thể đó.

Ví dụ: nếu chúng ta có một câu lệnh lặp trong mã java:

while(i<10){
    // ...
    a=a+i;
    // ...
 }

Mã vòng lặp trên chạy trong 10 lần nếu giá trị của i bằng 0.

Không cần thiết phải biên dịch mã byte trong 10 lần nữa vì lệnh tương tự sẽ được thực thi trong 10 lần. Trong trường hợp đó, chỉ cần biên dịch mã đó một lần và giá trị có thể được thay đổi cho số lần yêu cầu. Vì vậy, Trình biên dịch Just In Time (JIT) theo dõi các câu lệnh và phương thức như vậy (như đã nói ở trên) và biên dịch các đoạn mã byte đó thành mã máy để có hiệu suất tốt hơn.

Một ví dụ tương tự khác, đó là tìm kiếm một mẫu bằng cách sử dụng "Biểu thức chính quy" trong danh sách các chuỗi / câu.

Trình biên dịch JIT không biên dịch tất cả mã thành mã máy. Nó biên dịch mã có một mẫu tương tự trong thời gian chạy.

Xem tài liệu này của Oracle về Hiểu JIT để đọc thêm.


"Không cần thiết phải biên dịch mã byte trong 10 lần nữa vì cùng một lệnh sẽ thực thi trong 10 lần" - một trình biên dịch thông thường thì sao? Nó biên dịch mảnh này nhiều lần?
TT_

4

Bạn có mã được bổ sung vào một số IL (ngôn ngữ trung gian). Khi bạn chạy chương trình của mình, máy tính không hiểu mã này. Nó chỉ hiểu mã bản địa. Vì vậy, trình biên dịch JIT biên dịch IL của bạn thành mã gốc khi đang di chuyển. Nó làm điều này ở cấp độ phương pháp.


2
"Cấp độ phương pháp" nghĩa là gì?
Koray Tugay

4

Tôi biết đây là một chủ đề cũ, nhưng tối ưu hóa thời gian chạy là một phần quan trọng khác của quá trình biên dịch JIT dường như không được thảo luận ở đây. Về cơ bản, trình biên dịch JIT có thể giám sát chương trình khi nó chạy để xác định các cách để cải thiện việc thực thi. Sau đó, nó có thể thực hiện những thay đổi đó một cách nhanh chóng - trong thời gian chạy. Tối ưu hóa Google JIT (javaworld có một bài viết khá hay về nó. )


3

Trình biên dịch đúng lúc (JIT) là một phần mềm nhận được đầu vào không thực thi và trả về mã máy thích hợp sẽ được thực thi. Ví dụ:

Intermediate representation    JIT    Native machine code for the current CPU architecture

     Java bytecode            --->        machine code
     Javascript (run with V8) --->        machine code

Hậu quả của điều này là đối với một kiến ​​trúc CPU nhất định, trình biên dịch JIT thích hợp phải được cài đặt.

Trình biên dịch khác nhau, trình thông dịch và JIT

Mặc dù có thể có ngoại lệ nói chung khi chúng ta muốn chuyển đổi mã nguồn thành mã máy, chúng ta có thể sử dụng:

  1. Trình biên dịch : Lấy mã nguồn và trả về một tệp thực thi
  2. Thông dịch viên : Thực hiện hướng dẫn chương trình theo hướng dẫn. Nó nhận một phân đoạn thực thi của mã nguồn và biến phân đoạn đó thành các hướng dẫn máy. Quá trình này được lặp lại cho đến khi tất cả mã nguồn được chuyển thành hướng dẫn máy và được thực thi.
  3. JIT : Có thể thực hiện nhiều cách khác nhau của JIT, tuy nhiên JIT thường là sự kết hợp giữa trình biên dịch và trình thông dịch. Đầu tiên JIT biến dữ liệu trung gian (ví dụ: mã byte Java) mà nó nhận được thành ngôn ngữ máy thông qua giải thích. Một JIT thường có thể cảm nhận khi một phần nhất định của mã được thực thi thường xuyên và sẽ biên dịch phần này để thực thi nhanh hơn.

2

Jit là viết tắt của trình biên dịch chỉ trong thời gian jit là một chương trình biến mã byte java thành lệnh có thể được gửi trực tiếp đến bộ xử lý.

Sử dụng java chỉ trong trình biên dịch thời gian (thực sự là trình biên dịch thứ hai) ở nền tảng hệ thống cụ thể tuân theo mã byte thành mã hệ thống cụ thể, một khi mã được biên dịch lại bởi trình biên dịch jit, nó thường sẽ chạy nhanh hơn trong máy tính.

Trình biên dịch đúng lúc đi kèm với máy ảo và được sử dụng tùy chọn. Nó biên dịch mã byte thành mã thực thi dành riêng cho nền tảng được thực thi ngay lập tức.


2

just-in-time (JIT) biên soạn, (còn động dịch hoặc thời gian chạy biên dịch), là một cách để thực thi mã máy tính đó liên quan đến việc biên soạn trong khi thực hiện một chương trình - vào thời gian chạy - chứ không phải trước khi thực hiện .

Biên dịch CNTT là sự kết hợp của hai cách tiếp cận truyền thống để dịch sang mã máy - biên dịch trước thời hạn (AOT)giải thích - và kết hợp một số ưu điểm và nhược điểm của cả hai. Biên dịch JIT kết hợp tốc độ của mã được biên dịch với tính linh hoạt của giải thích .

Hãy xem xét JIT được sử dụng trong JVM,

Ví dụ, trình biên dịch JVM HotSpot tạo ra tối ưu hóa động. Nói cách khác, họ đưa ra quyết định tối ưu hóa trong khi ứng dụng Java đang chạy và tạo ra các hướng dẫn máy gốc hiệu năng cao được nhắm mục tiêu cho kiến ​​trúc hệ thống cơ bản.

Khi một phương thức được chọn để biên dịch, JVM cung cấp mã byte của nó cho trình biên dịch Just-In-Time (JIT). JIT cần hiểu ngữ nghĩa và cú pháp của mã byte trước khi có thể biên dịch phương thức chính xác. Để giúp trình biên dịch JIT phân tích phương thức, mã byte của nó trước tiên được định dạng lại trong một biểu diễn bên trong được gọi là cây theo dõi, giống với mã máy gần hơn mã byte. Phân tích và tối ưu hóa sau đó được thực hiện trên cây của phương pháp. Cuối cùng, các cây được dịch sang mã gốc.

Cây theo dõi là một cấu trúc dữ liệu được sử dụng trong quá trình biên dịch mã lập trình thời gian chạy. Cây dấu vết được sử dụng trong một loại 'chỉ trong trình biên dịch thời gian' theo dõi việc thực thi mã trong các điểm nóng và biên dịch nó. Tham khảo điều này .

Tham khảo :


1

Trình biên dịch không phải JIT lấy mã nguồn và biến đổi nó thành mã byte cụ thể của máy tại thời gian biên dịch. Trình biên dịch JIT lấy mã byte bất khả tri của máy được tạo ra trong thời gian biên dịch và biến nó thành mã byte cụ thể của máy trong thời gian chạy. Trình biên dịch JIT mà Java sử dụng là những gì cho phép một nhị phân duy nhất chạy trên nhiều nền tảng mà không cần sửa đổi.


0

20% mã byte được sử dụng 80% thời gian. Trình biên dịch JIT có được các số liệu thống kê này và tối ưu hóa 20% mã byte này để chạy nhanh hơn bằng cách thêm các phương thức nội tuyến, loại bỏ các khóa không sử dụng, v.v. và cũng tạo mã byte cụ thể cho máy đó. Tôi đang trích dẫn từ bài viết này, tôi thấy nó rất tiện dụng. http://java.dzone.com/articles/just-time-compiler-jit-hotspot


Không chắc chắn tại sao điều này được đánh dấu -1. Tôi nghĩ vấn đề ở đây là thống kê thời gian chạy được sử dụng để giúp tối ưu hóa.
eze

Có, nhưng câu trả lời đã không diễn đạt như thế. Theo nghĩa đen, JIT không tối ưu hóa 20% mã nóng nhất.
mabraham

0

JIT đề cập đến công cụ thực thi trong một vài triển khai JVM, một công cụ nhanh hơn nhưng đòi hỏi nhiều bộ nhớ hơn, là một trình biên dịch đúng lúc. Trong sơ đồ này, mã byte của một phương thức được biên dịch thành mã máy gốc khi lần đầu tiên phương thức được gọi. Mã máy gốc cho phương thức sau đó được lưu vào bộ đệm, vì vậy nó có thể được sử dụng lại vào lần tiếp theo khi phương thức tương tự được gọi.


2
Tôi sẽ tránh trả lời câu hỏi như thế này nếu bạn không cung cấp một cái gì đó mới / tốt hơn. Nếu bạn nhận được bất kỳ phản ứng nào, đó có thể là một lời chỉ trích hoặc chỉ trích: Câu trả lời của bạn không chính xác. "JIT" không giới hạn ở Máy ảo Java , "nhanh hơn nhưng sử dụng nhiều bộ nhớ hơn" là một hiệu ứng có thể có nhưng không phải là khái niệm JIT và các phương thức thường không được biên dịch trong lần gọi đầu tiên, thay vào đó sau một vài lần khi nó trở nên rõ ràng dành thời gian cho JIT'ing là lợi thế tổng thể.
zapl

0

JVM thực sự thực hiện các bước biên dịch trong thời gian chạy vì lý do hiệu năng. Điều này có nghĩa là Java không có sự phân tách thực thi biên dịch sạch. Đầu tiên, nó được gọi là biên dịch tĩnh từ mã nguồn Java sang mã byte. Sau đó, mã byte này được truyền cho JVM để thực thi. Nhưng việc thực thi mã byte là chậm nên JVM đo tần suất chạy mã byte và khi phát hiện "điểm nóng" mã chạy rất thường xuyên, nó thực hiện biên dịch động từ mã byte sang mã máy của mã "hotspot" (hotspot profiler). Vì vậy, ngày nay các chương trình Java được chạy bằng thực thi machinecode.


0

Trình biên dịch Just In Time còn được gọi là trình biên dịch JIT được sử dụng để cải thiện hiệu năng trong Java. Nó được kích hoạt theo mặc định. Nó được biên dịch được thực hiện tại thời điểm thực hiện sớm hơn. Java đã phổ biến việc sử dụng trình biên dịch JIT bằng cách đưa nó vào JVM.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.