Apa yang dilakukan oleh kompiler just-in-time (JIT)?

Jawaban:

518

Kompiler JIT berjalan setelah program dimulai dan mengkompilasi kode (biasanya bytecode atau semacam instruksi VM) dengan cepat (atau disebut tepat waktu) seperti yang disebut) menjadi bentuk yang biasanya lebih cepat, biasanya host asli CPU set instruksi. JIT memiliki akses ke informasi runtime dinamis sedangkan kompiler standar tidak dan dapat membuat optimasi yang lebih baik seperti fungsi inlining yang sering digunakan.

Ini berbeda dengan kompiler tradisional yang mengkompilasi semua kode ke bahasa mesin sebelum program dijalankan pertama kali.

Untuk parafrase, kompiler konvensional membangun seluruh program sebagai file EXE SEBELUM pertama kali Anda menjalankannya. Untuk program gaya yang lebih baru, perakitan dibuat dengan pseudocode (p-code). Hanya SETELAH Anda menjalankan program pada OS (mis., Dengan mengklik dua kali ikonnya) akan kompiler (JIT) menendang dan menghasilkan kode mesin (m-code) yang prosesor Intel atau apa pun akan mengerti.

Mark Cidade
sumber
16
Dan berbeda dengan kode yang ditafsirkan, yang mulai menjalankan instruksi bytecode atau VM segera tanpa penundaan, tetapi akan menjalankan instruksi lebih lambat dari bahasa mesin.
Aaron
3
JIT sering digunakan dengan kode yang ditafsirkan untuk mengubahnya menjadi bahasa mesin tapi ya, kode yang ditafsirkan murni (tanpa JITting apa pun) lambat. Bahkan bytecode Java tanpa JITter sangat lambat.
Mark Cidade
48
Targetnya tidak harus berupa kode mesin. JRuby memiliki kompiler JIT yang akan mengkompilasi kode sumber Ruby ke bytecode Java setelah beberapa doa. Kemudian, setelah beberapa doa lainnya, kompiler JVM JIT menendang dan mengkompilasi bytecode ke kode asli.
Jörg W Mittag
4
Perlu dicatat bahwa, sebagaimana disinggung oleh Jörg, JIT tidak harus langsung digunakan. Seringkali, kode akan ditafsirkan sampai ditentukan bahwa itu akan bernilai JITting. Karena JITting dapat menyebabkan penundaan, mungkin lebih cepat untuk TIDAK JIT beberapa kode jika jarang digunakan dan dengan demikian respon cepat lebih penting daripada runtime keseluruhan.
Adam Jaskiewicz
3
@ErikReppen: Jika mesin baru keluar, mengkompilasi dan mengoptimalkan program untuk mesin baru itu menggunakan kompiler konvensional kemungkinan akan menghasilkan hasil lebih cepat daripada JIT. Di sisi lain, JIT yang dioptimalkan untuk mesin baru itu akan dapat dapat mengoptimalkan kinerja kode yang diterbitkan sebelum mesin baru itu ditemukan .
supercat
255

Pada awalnya, kompiler bertanggung jawab untuk mengubah bahasa tingkat tinggi (didefinisikan sebagai tingkat yang lebih tinggi dari assembler) menjadi kode objek (instruksi mesin), yang kemudian akan dihubungkan (oleh linker) menjadi yang dapat dieksekusi.

Pada satu titik dalam evolusi bahasa, kompiler akan mengkompilasi bahasa tingkat tinggi ke dalam pseudo-code, yang kemudian akan ditafsirkan (oleh penerjemah) untuk menjalankan program Anda. Ini menghilangkan kode objek dan executable, dan memungkinkan bahasa-bahasa ini menjadi portabel untuk beberapa sistem operasi dan platform perangkat keras. Pascal (yang dikompilasi ke P-Code) adalah salah satu yang pertama; Java dan C # adalah contoh yang lebih baru. Akhirnya istilah P-Code diganti dengan bytecode, karena sebagian besar operasi pseudo adalah byte panjang.

Kompiler Just-In-Time (JIT) adalah fitur interpreter run-time, yang alih-alih menafsirkan bytecode setiap kali metode dipanggil, akan mengkompilasi bytecode ke dalam instruksi kode mesin dari mesin yang sedang berjalan, dan kemudian memohon ini kode objek sebagai gantinya. Idealnya, efisiensi menjalankan kode objek akan mengatasi ketidakefisienan mengkompilasi ulang program setiap kali dijalankan.

Craig Trader
sumber
5
Namun frasa "kompiler Just-In-Time (JIT) ini adalah fitur dari penerjemah run-time" menyebabkan kebingungan; misalnya - stackoverflow.com/questions/16439512/…
Stephen C
11
Sebenarnya, JIT adalah add-on, dan Anda masih bisa menonaktifkannya menggunakan parameter -Xint ke Java, jadi itu hanya fitur.
Craig Trader
3
Saya tidak sepenuhnya setuju. JIT bukan evolusi - ini adalah alternatif dari kompiler klasik.
i486
1
JIT adalah satu langkah di jalur evolusi dari sakelar mekanis kabel ke menentukan kriteria pencarian dengan mengatakan "OK Google" ke ponsel pintar Anda. JIT saat ini tersedia sebagai bagian dari Java 7/8 adalah lompatan dan batas di luar apa yang tersedia sebagai bagian dari Java 2 - itu evolusi juga.
Craig Trader
1
@ i486 - Sun / Oracle have (AFAIK) tidak pernah mengirim kompiler klasik ("sebelumnya") untuk Java yang menghasilkan kode asli. Sangatlah sulit untuk berpendapat bahwa JIT adalah sebuah alternatif ... ketika mereka menganggapnya sebagai alternatif untuk tidak pernah dikirimkan. (Saya mengabaikan kompiler GCJ AOT karena itu tidak ada hubungannya dengan Sun / Oracle, dan itu juga bukan solusi yang lengkap. Hal ini tentunya tidak dapat dilakukan sekarang.)
Stephen C
69

JIT-Tepat pada waktunya kata itu sendiri mengatakan kapan dibutuhkan (sesuai permintaan)

Skenario khas:

Kode sumber sepenuhnya dikonversi menjadi kode mesin

Skenario JIT:

Kode sumber akan dikonversi menjadi bahasa assembly seperti struktur [untuk ex IL (bahasa perantara) untuk C #, ByteCode untuk java].

Kode menengah dikonversi menjadi bahasa mesin hanya ketika aplikasi membutuhkan kode yang diperlukan hanya dikonversi ke kode mesin.

JIT vs Non-JIT perbandingan:

  • Dalam JIT tidak semua kode diubah menjadi kode mesin terlebih dahulu bagian dari kode yang diperlukan akan dikonversi menjadi kode mesin kemudian jika metode atau fungsi yang disebut tidak ada dalam mesin maka itu akan diubah menjadi kode mesin ... itu mengurangi beban pada CPU.

  • Karena kode mesin akan dihasilkan pada waktu berjalan .... kompiler JIT akan menghasilkan kode mesin yang dioptimalkan untuk menjalankan arsitektur CPU mesin.

Contoh JIT:

  1. Di Java, JIT ada di JVM (Java Virtual Machine)
  2. Dalam C # itu dalam CLR (Common Language Runtime)
  3. Di Android ada di DVM (Dalvik Virtual Machine), atau ART (Android RunTime) di versi yang lebih baru.
Durai Amuthan.H
sumber
7
JIT menawarkan beberapa keunggulan khusus dalam kerangka kerja dengan dukungan untuk tipe generik nyata; itu mungkin untuk mendefinisikan metode generik yang akan mampu menghasilkan berbagai jenis tanpa batas, masing-masing akan memerlukan kode mesin yang berbeda, tetapi hanya memiliki JIT menghasilkan kode untuk jenis yang sebenarnya diproduksi. Sebaliknya, dalam C ++ perlu bahwa kompiler menghasilkan kode untuk semua jenis program yang pernah digunakan.
supercat
6
JVM bukan kode JIT saat pertama kali menjalankannya. Beberapa kali pertama, ia menerjemahkan bytecode. Kemudian, jika kode itu berjalan cukup sering, mungkin memutuskan untuk mengganggu JITting.
ninjalj
1
Anda mengatakan JIT di Jawa adalah JVM. Namun kami sudah menyediakan kode yang dikompilasi untuk JVM, bukan? Lalu itu mengkompilasinya lagi maksud Anda?
Koray Tugay
@KorayTugay - Kami menyediakan Bytecodes ke JVM dan JVM akan mengonversi sebagian dari itu ke kode mesin sesuai permintaan. Sumber daya disimpan.
Durai Amuthan.H
1
Di Jawa, JIT bukan JVM. Itu hanya sebagian saja.
happs
25

Seperti yang lain telah disebutkan

JIT adalah singkatan dari Just-in-Time yang berarti bahwa kode dikompilasi ketika dibutuhkan, bukan sebelum runtime.

Hanya untuk menambahkan satu poin ke diskusi di atas, JVM mempertahankan hitungan berapa kali suatu fungsi dieksekusi. Jika jumlah ini melebihi batas yang telah ditentukan, JIT mengkompilasi kode ke dalam bahasa mesin yang dapat langsung dieksekusi oleh prosesor (tidak seperti kasus normal di mana javac mengkompilasi kode menjadi bytecode dan kemudian java - penerjemah menginterpretasikan bytecode ini baris demi baris mengubahnya menjadi kode mesin dan jalankan).

Juga lain kali fungsi ini dihitung kode terkompilasi yang sama dieksekusi lagi tidak seperti interpretasi normal di mana kode ditafsirkan lagi baris demi baris. Ini membuat eksekusi lebih cepat.

Aniket Thakur
sumber
14

Kompiler JIT hanya mengkompilasi kode byte ke kode asli yang setara pada eksekusi pertama. Setelah setiap eksekusi berturut-turut, JVM hanya menggunakan kode asli yang sudah dikompilasi untuk mengoptimalkan kinerja.

masukkan deskripsi gambar di sini

Tanpa kompiler JIT, juru bahasa JVM menerjemahkan kode byte baris demi baris untuk membuatnya tampak seolah-olah aplikasi asli sedang dijalankan.

masukkan deskripsi gambar di sini

Sumber


sumber
1
Penafsiran saya tentang JIT adalah bahwa ia bertindak seperti memoisasi, di mana fungsi yang sering digunakan 'disimpan' dan biaya kompilasi dari bytecode java ke kode asli yang bergantung pada ISA dilewati. Jika ini benar, mengapa java tidak mengkompilasi sepenuhnya ke kode asli dari awal? Ini akan mengurangi segala jenis kompilasi run-time dan menjadikan java 'asli' ke mesin?
Michael Choi
12

JIT adalah singkatan dari Just-in-Time yang berarti bahwa kode dikompilasi ketika dibutuhkan, bukan sebelum runtime.

Ini bermanfaat karena kompiler dapat menghasilkan kode yang dioptimalkan untuk mesin khusus Anda. Kompiler statis, seperti kompiler C rata-rata, akan mengkompilasi semua kode ke kode yang dapat dieksekusi pada mesin pengembang. Karenanya kompiler akan melakukan optimisasi berdasarkan beberapa asumsi. Ini dapat mengkompilasi lebih lambat dan melakukan lebih banyak optimasi karena tidak memperlambat eksekusi program untuk pengguna.

Brian Lyttle
sumber
Mengapa kode yang dikompilasi tidak disimpan di suatu tempat di komputer pengguna sehingga pada saat aplikasi dijalankan JIT tidak harus mengkompilasi ulang lagi?
omerfarukdogan
Pengamatan yang bagus. Dimungkinkan untuk melakukan ini, tetapi apakah itu benar-benar menguntungkan tergantung pada platform dan penggunaan aplikasi. Pengoptimalan JIT tidak harus sama dengan offline, atau pengoptimalan sebelumnya sehingga manfaatnya mungkin hanya 'bukan JITting' yang mungkin, atau mungkin tidak banyak membantu.
Brian Lyttle
9

Setelah kode byte (yang netral arsitektur) telah dihasilkan oleh kompiler Java, eksekusi akan ditangani oleh JVM (di Jawa). Kode byte akan dimuat ke JVM oleh loader dan kemudian setiap instruksi byte ditafsirkan.

Ketika kita perlu memanggil metode beberapa kali, kita perlu menafsirkan kode yang sama berkali-kali dan ini mungkin membutuhkan waktu lebih lama daripada yang dibutuhkan. Jadi kami memiliki kompiler JIT (tepat waktu). Ketika byte telah dimuat ke JVM (run time-nya), seluruh kode akan dikompilasi daripada ditafsirkan, sehingga menghemat waktu.

Kompiler JIT hanya berfungsi saat run time, jadi kami tidak memiliki output biner.

Pengguna
sumber
2
Seluruh kode tidak dikompilasi ketika dimuat ke JVM, karena ada sedikit informasi (baca: panduan) tentang bagaimana cara kompilasi. Perlu diingat bahwa kinerja adalah tujuan akhir. JIT agak selektif: memantau dan memilih metode yang paling populer untuk optimasi. Dan itu terus melakukan ini sampai tingkat optimalisasi maksimum telah dicapai untuk metode individual.
Yaw Boakye
7

Just In Time Compiler (JIT):
Ini mengkompilasi bytecode java menjadi instruksi mesin dari CPU tertentu.

Misalnya, jika kita memiliki pernyataan loop dalam kode java kita:

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

Kode loop di atas berjalan 10 kali jika nilai i adalah 0.

Tidak perlu mengkompilasi bytecode sebanyak 10 kali lagi dan lagi karena instruksi yang sama akan dieksekusi untuk 10 kali. Dalam hal ini, perlu untuk mengkompilasi kode itu hanya sekali dan nilainya dapat diubah untuk jumlah yang diperlukan kali. Jadi, Just In Time (JIT) Compiler melacak pernyataan dan metode tersebut (seperti yang disebutkan di atas sebelumnya) dan mengkompilasi potongan kode byte tersebut ke dalam kode mesin untuk kinerja yang lebih baik.

Contoh serupa lainnya, adalah pencarian pola menggunakan "Ekspresi Reguler" dalam daftar string / kalimat.

JIT Compiler tidak mengkompilasi semua kode ke kode mesin. Ini mengkompilasi kode yang memiliki pola yang sama saat dijalankan.

Lihat dokumentasi Oracle ini pada Understand JIT untuk membaca lebih lanjut.

Anands23
sumber
"Tidak perlu mengkompilasi bytecode untuk 10 kali lagi dan lagi karena instruksi yang sama akan dieksekusi untuk 10 kali" - bagaimana dengan kompiler biasa? Apakah ini mengkompilasi bagian ini beberapa kali?
TT_
4

Anda memiliki kode yang dikompilasi ke beberapa IL (bahasa perantara). Ketika Anda menjalankan program Anda, komputer tidak memahami kode ini. Itu hanya mengerti kode asli. Jadi kompiler JIT mengkompilasi IL Anda ke dalam kode asli dengan cepat. Ini dilakukan pada level metode.

Charles Graham
sumber
2
Apa maksudmu "tingkat metode"?
Koray Tugay
4

Saya tahu ini adalah utas lama, tetapi optimasi runtime adalah bagian penting lain dari kompilasi JIT yang sepertinya tidak dibahas di sini. Pada dasarnya, kompiler JIT dapat memonitor program saat dijalankan untuk menentukan cara untuk meningkatkan eksekusi. Kemudian, ia dapat membuat perubahan tersebut dengan cepat - saat runtime. Google JIT optimisasi (javaworld memiliki artikel yang cukup bagus tentangnya. )

Eze
sumber
3

Just in time compiler (JIT) adalah perangkat lunak yang menerima input yang tidak dapat dieksekusi dan mengembalikan kode mesin yang sesuai untuk dieksekusi. Sebagai contoh:

Intermediate representation    JIT    Native machine code for the current CPU architecture

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

Konsekuensi dari ini adalah bahwa untuk arsitektur CPU tertentu kompiler JIT yang sesuai harus diinstal.

Perbedaan kompiler, interpreter, dan JIT

Meskipun ada pengecualian secara umum ketika kita ingin mengubah kode sumber menjadi kode mesin kita dapat menggunakan:

  1. Penyusun : Mengambil kode sumber dan mengembalikan yang dapat dieksekusi
  2. Penerjemah : Menjalankan instruksi program dengan instruksi. Dibutuhkan segmen yang dapat dieksekusi dari kode sumber dan mengubah segmen itu menjadi instruksi mesin. Proses ini diulangi sampai semua kode sumber ditransformasikan menjadi instruksi mesin dan dieksekusi.
  3. JIT : Banyak implementasi JIT yang berbeda dimungkinkan, namun JIT biasanya merupakan kombinasi dari kompiler dan interpreter. JIT pertama-tama mengubah data perantara (mis. Java bytecode) yang diterimanya ke dalam bahasa mesin melalui interpretasi. JIT sering dapat merasakan ketika bagian tertentu dari kode dieksekusi sering dan akan mengkompilasi bagian ini untuk eksekusi lebih cepat.
Willem van der Veen
sumber
2

Jit singkatan dari just in time compiler jit adalah program yang mengubah kode byte java menjadi instruksi yang dapat dikirim langsung ke prosesor.

Menggunakan java just in time compiler (benar-benar kompiler kedua) pada platform sistem tertentu memenuhi bytecode ke dalam kode sistem tertentu, setelah kode telah dikompilasi ulang oleh jit complier, biasanya akan berjalan lebih cepat di komputer.

Compiler just-in-time dilengkapi dengan mesin virtual dan digunakan secara opsional. Ini mengkompilasi bytecode ke dalam kode yang dapat dieksekusi platform-spesifik yang segera dieksekusi.

pengguna3459027
sumber
2

kompilasi just-in-time (JIT), (juga terjemahan dinamis atau kompilasi run-time), adalah cara mengeksekusi kode komputer yang melibatkan kompilasi selama eksekusi suatu program - pada saat run time - daripada sebelum dieksekusi .

Kompilasi TI adalah kombinasi dari dua pendekatan tradisional untuk terjemahan ke kode mesin - kompilasi di depan waktu (AOT) , dan interpretasi - dan menggabungkan beberapa keuntungan dan kelemahan dari keduanya. Kompilasi JIT menggabungkan kecepatan kode yang dikompilasi dengan fleksibilitas interpretasi .

Mari kita pertimbangkan JIT yang digunakan dalam JVM,

Sebagai contoh, kompiler JS HotSpot JVM menghasilkan optimasi dinamis. Dengan kata lain, mereka membuat keputusan optimisasi saat aplikasi Java sedang berjalan dan menghasilkan instruksi mesin asli berkinerja tinggi yang ditargetkan untuk arsitektur sistem yang mendasarinya.

Ketika suatu metode dipilih untuk kompilasi, JVM memasukkan bytecode-nya ke kompiler Just-In-Time (JIT). JIT perlu memahami semantik dan sintaks dari bytecode sebelum dapat mengkompilasi metode dengan benar. Untuk membantu kompiler JIT menganalisis metode ini, bytecode-nya terlebih dahulu dirumuskan kembali dalam representasi internal yang disebut pohon jejak, yang menyerupai kode mesin lebih dekat daripada bytecode. Analisis dan optimisasi kemudian dilakukan pada pohon metode. Pada akhirnya, pohon-pohon tersebut diterjemahkan ke dalam kode asli.

Pohon jejak adalah struktur data yang digunakan dalam kompilasi runtime dari kode pemrograman. Trace tree digunakan dalam jenis 'just in time compiler' yang melacak kode yang dieksekusi selama hotspot dan mengkompilasinya. Lihat ini .

Merujuk:

utama
sumber
1

Kompiler non-JIT mengambil kode sumber dan mengubahnya menjadi kode byte khusus mesin pada waktu kompilasi. Sebuah kompiler JIT mengambil kode byte mesin agnostik yang dihasilkan pada waktu kompilasi dan mengubahnya menjadi kode byte spesifik mesin pada saat run time. Kompiler JIT yang digunakan Java adalah apa yang memungkinkan biner tunggal berjalan pada banyak platform tanpa modifikasi.


sumber
0

20% dari kode byte digunakan 80% dari waktu. Kompiler JIT mendapatkan statistik ini dan mengoptimalkan 20% dari kode byte ini untuk berjalan lebih cepat dengan menambahkan metode inline, penghapusan kunci yang tidak digunakan dll dan juga membuat bytecode khusus untuk mesin itu. Saya mengutip dari artikel ini, saya merasa itu berguna. http://java.dzone.com/articles/just-time-compiler-jit-hotspot

Santosh budhe
sumber
Tidak yakin mengapa ini ditandai -1. Saya pikir intinya di sini adalah statistik run time digunakan untuk membantu mengoptimalkan.
Yeh
Ya, tapi jawabannya tidak seperti itu. Secara harfiah, JIT tidak mengoptimalkan 20% kode yang terpanas.
mabraham
0

JIT merujuk ke mesin eksekusi di beberapa implementasi JVM, yang lebih cepat tetapi membutuhkan lebih banyak memori, adalah kompiler just-in-time. Dalam skema ini, bytecode metode dikompilasi ke kode mesin asli saat metode pertama kali dipanggil. Kode mesin asli untuk metode ini kemudian di-cache, sehingga dapat digunakan kembali saat berikutnya metode yang sama dipanggil.

Venkata Santhosh Piduri
sumber
2
Saya akan menghindari menjawab pertanyaan seperti ini jika Anda tidak memberikan sesuatu yang baru / lebih baik. Jika Anda mendapat reaksi apa pun, mungkin itu adalah downvote atau kritik: Jawaban Anda tidak tepat. "JIT" tidak terbatas pada Java Virtual Machine , "lebih cepat tetapi menggunakan lebih banyak memori" adalah efek yang mungkin tetapi tidak melekat pada konsep JIT, dan metode sering tidak dikompilasi pada doa pertama, melainkan setelah beberapa ketika menjadi jelas bahwa menghabiskan waktu di JIT'ing secara keseluruhan menguntungkan.
zapl
0

JVM benar-benar melakukan langkah kompilasi selama runtime karena alasan kinerja. Ini berarti bahwa Java tidak memiliki pemisahan kompilasi-eksekusi bersih. Pertama melakukan kompilasi statis dari kode sumber Java ke bytecode. Kemudian bytecode ini diteruskan ke JVM untuk dieksekusi. Tetapi mengeksekusi bytecode lambat sehingga JVM mengukur seberapa sering bytecode dijalankan dan ketika mendeteksi "hotspot" dari kode yang berjalan sangat sering ia melakukan kompilasi dinamis dari bytecode ke machinecode dari kode "hotspot" (hotspot profiler). Jadi secara efektif saat ini program Java dijalankan oleh eksekusi kode mesin.

Hai, India
sumber
0

Kompiler Just In Time juga dikenal sebagai kompiler JIT digunakan untuk peningkatan kinerja di Jawa. Ini diaktifkan secara default. Ini adalah kompilasi yang dilakukan pada waktu eksekusi lebih awal. Java telah mempopulerkan penggunaan kompiler JIT dengan memasukkannya ke dalam JVM.

Ganesh Giri
sumber