Mengapa bahasa VM tidak dikompilasi sekali saja?

8

(Pertama-tama, saya harus menjelaskan bahwa kompiler dan mesin virtual ( alias ) adalah bidang yang sama sekali tidak dikenal bagi saya)

Seperti yang saya pahami, setiap kali aplikasi Java / C # / ... dijalankan, VM dipanggil dan menerjemahkan kode perantara (bytecode, CIL, dll) ke instruksi mesin.

Tetapi mengapa operasi ini tidak dapat dilakukan hanya sekali - pada waktu instalasi?

vemv
sumber
1
Apa itu waktu pemasangan?
Peter Taylor
3
Tidak yakin apakah itu istilah standar, tapi maksud saya: ketika pengguna menginstal program - membukanya untuk pertama kali -, dibandingkan dengan mengkompilasi program di mesin pengembang (yang tidak bisa mengetahui platform yang akan digunakan oleh pengguna tertentu - dan Anda tidak ingin mendistribusikan satu installer per platform).
vemv
Kompilasi @vemv pada saat runtime memungkinkan VM untuk mengkhususkan instruksi mesin untuk perangkat keras khusus Anda
Lucina

Jawaban:

8

Dalam kasus Java, JVM dapat melakukan optimasi yang melintasi batas perpustakaan. Misalnya, Anda dapat menguraikan metode dari pustaka ke dalam kode klien Anda sendiri. Jenis optimasi ini tidak dapat dilakukan pada waktu kompilasi, karena perpustakaan dapat berubah sebelum eksekusi. Sangat mungkin libfoo-1.0 Anda digantikan oleh libfoo-1.1 tanpa kompilasi ulang. Jika itu terjadi, inline pustaka yang dilakukan pada waktu kompilasi akan menjadi sama sekali tidak valid.

Dengan melakukan optimasi hanya pada saat runtime, tidak ada kekhawatiran bahwa perubahan pustaka di bawah Anda akan membatalkan optimasi.

Steven Schlansker
sumber
1
Sebuah inline bisa jadi alih-alih menghasilkan kode mesin untuk memanggil "Y.setX (x)" (di mana Y berasal dari pustaka bagian ketiga) yang kemudian menjalankan "this.x = x" kemudian hanya menghasilkan kode mesin untuk "Yx = x ".
Singkatnya, runtime memiliki informasi yang waktu kompilasi tidak.
Daniel Gratzer
6

Karena ini mencegah mereka menggunakan banyak fitur. Sebagai contoh, bagaimana JIT dapat menghasilkan instance generik baru dari DLL yang dimuat saat run-time? DLL itu tidak ada pada saat instalasi.

DeadMG
sumber
1
Sorakan untuk jawabannya. Saya rasa saya mendapatkan masalah instantation - tidak bisa 100% yakin karena balasan Anda agak terlalu sok. Juga daftar fitur lain yang tidak tersedia akan membuat poin Anda lebih kuat.
vemv
3
Atau secara umum: JIT dapat melakukan optimasi berdasarkan input; DLL yang dimuat saat run-time adalah salah satu jenis input.
amara
1
Jelas, mereka DLL dipasang juga, dan masing-masing DLL dapat dikompilasi pada nya waktu install. Anda kehilangan optimisasi lintas-modul, tetapi itu agak teoretis.
MSalters
@MSalters: Tidak setiap DLL memiliki waktu "instal".
DeadMG
@DeadMG: Bagaimanapun juga, kita sedang membahas sistem hipotetis; sistem seperti itu mungkin dengan mudah memerlukan instalasi. (Ini akan menjadi manfaat keamanan, tambahan, jika pengenalan kode yang dapat dieksekusi akan dikelola secara eksplisit).
MSalters
5

Bisa dan sering, setidaknya dengan aplikasi .NET. Lihat Native Image Generator

alat yang meningkatkan kinerja aplikasi yang dikelola. Ngen.exe membuat gambar asli, yaitu file yang berisi kode mesin khusus prosesor yang dikompilasi, dan menginstalnya ke dalam cache gambar asli di komputer lokal. Runtime dapat menggunakan gambar asli dari cache alih-alih menggunakan kompilator just-in-time (JIT) untuk mengkompilasi rakitan asli ...

Nemanja Trifunovic
sumber
Perhatikan bahwa ini juga mirip dengan Android Runtime (ART) yang dibangun oleh Google untuk meningkatkan kinerja Aplikasi Android
neelsg
3

Untuk mengulangi pertanyaan sesuai dengan klarifikasi:

Mengapa bytecode tidak bisa dikompilasi ke kode asli saat pertama kali program dijalankan?

Saya melihat masalah berikut:

  • Di mana hasil disimpan? Anda tidak dapat mengasumsikan bahwa file yang mengandung bytecode dapat ditulis; Anda tidak ingin menggembungkan mesin pengembang dengan membuang .exe baru ke penyimpanan permanen setiap kali ia menjalankan tes; dan jika Anda menyimpan file dalam penyimpanan sementara maka file itu akan hilang pada saat Anda reboot, jadi Anda belum mendapatkan banyak.

  • Anda menukar startup yang sedikit lambat setiap kali dengan startup yang sangat lambat pertama kali. Tidak akan meninggalkan kesan hebat pada klien.

  • Anda akan mengalami masalah signifikan dengan pemuatan kelas dinamis.

Peter Taylor
sumber
2
Poin pertama adalah sepele. Cache dipahami dengan cukup baik. Ketika bytecode yang dapat dieksekusi yang mendasar dihapus, Anda dapat menghapus entri cache terkait, dan juga jika itu tidak berjalan terlalu lama. Adapun poin kedua, Anda dapat melakukan kompilasi metode yang tidak digunakan di utas latar belakang. Ini seharusnya tidak menghalangi waktu startup, di mana Anda mengkompilasi metode yang disebut di latar depan.
MSalters
Sejauh yang saya mengerti, pertanyaannya bukan tentang mengkompilasi pada menjalankan pertama, tetapi mengkompilasi pada instalasi.
Nemanja Trifunovic
@NemanjaTrifunovic, baca komentar di pertanyaan.
Peter Taylor
1
Saya khawatir saya tidak menjelaskan diri saya dengan baik, maaf. Aku berarti pertama kalinya sebuah aplikasi yang pernah dijalankan, maka tidak ada kompilasi lebih lanjut akan diperlukan lagi. Sama seperti ketika Anda harus mengkompilasi program C sebelum menggunakannya di Linux.
vemv
1
Saya pikir ini dianggap sebagai instalasi - kompilasi / proses pembangunan tersebut sudah dituliskan untuk Anda.
vemv