JavaRush /Blog Java /Random-MS /Menyusun dan melaksanakan aplikasi Java di bawah hud
Павел Голов
Tahap
Москва

Menyusun dan melaksanakan aplikasi Java di bawah hud

Diterbitkan dalam kumpulan

Kandungan:

  1. pengenalan
  2. Menyusun kepada bytecode
  3. Contoh penyusunan dan pelaksanaan program
  4. Melaksanakan atur cara pada mesin maya
  5. Kompilasi Just-in-time (JIT).
  6. Kesimpulan
Menyusun dan melaksanakan aplikasi Java di bawah hud - 1

1. Pengenalan

Hai semua! Hari ini saya ingin berkongsi pengetahuan tentang apa yang berlaku di bawah hud JVM (Java Virtual Machine) selepas kami menjalankan aplikasi bertulis Java. Pada masa kini, terdapat persekitaran pembangunan yang bergaya yang membantu anda mengelak daripada memikirkan tentang dalaman JVM, menyusun dan melaksanakan kod Java, yang boleh menyebabkan pembangun baharu terlepas aspek penting ini. Pada masa yang sama, soalan mengenai topik ini sering ditanya semasa temuduga, sebab itu saya memutuskan untuk menulis artikel.

2. Penyusunan kepada bytecode

Menyusun dan melaksanakan aplikasi Java di bawah hud - 2
Mari kita mulakan dengan teori. Apabila kami menulis sebarang aplikasi, kami mencipta fail dengan sambungan .javadan meletakkan kod di dalamnya dalam bahasa pengaturcaraan Java. Fail sedemikian yang mengandungi kod boleh dibaca manusia dipanggil fail kod sumber . Setelah fail kod sumber sedia, anda perlu melaksanakannya! Tetapi pada peringkat ia mengandungi maklumat yang hanya boleh difahami oleh manusia. Java ialah bahasa pengaturcaraan berbilang platform. Ini bermakna program yang ditulis dalam Java boleh dilaksanakan pada mana-mana platform yang mempunyai sistem runtime Java khusus dipasang. Sistem ini dipanggil Java Virtual Machine (JVM). Untuk menterjemah program daripada kod sumber kepada kod yang JVM boleh faham, anda perlu menyusunnya. Kod yang difahami oleh JVM dipanggil bytecode dan mengandungi satu set arahan yang mesin maya akan laksanakan kemudiannya. Untuk menyusun kod sumber menjadi kod bait, terdapat pengkompil javacyang disertakan dalam JDK (Java Development Kit). Sebagai input, pengkompil menerima fail dengan sambungan .java, yang mengandungi kod sumber program, dan sebagai output, ia menghasilkan fail dengan sambungan .class, mengandungi kod bait yang diperlukan untuk atur cara dilaksanakan oleh mesin maya. Sebaik sahaja atur cara telah disusun menjadi kod bait, ia boleh dilaksanakan menggunakan mesin maya.

3. Contoh penyusunan dan pelaksanaan program

Katakan kita mempunyai program mudah, terkandung dalam fail Calculator.java, yang mengambil 2 argumen baris arahan angka dan mencetak hasil penambahannya:
class Calculator {
    public static void main(String[] args){
        int a = Integer.valueOf(args[0]);
        int b = Integer.valueOf(args[1]);

        System.out.println(a + b);
    }
}
Untuk menyusun atur cara ini ke dalam bytecode, kami akan menggunakan pengkompil javacpada baris arahan:
javac Calculator.java
Selepas penyusunan, kami menerima fail dengan bytecode sebagai output Calculator.class, yang boleh kami laksanakan menggunakan mesin java yang dipasang pada komputer kami menggunakan arahan java pada baris arahan:
java Calculator 1 2
Ambil perhatian bahawa selepas nama fail, 2 argumen baris perintah ditentukan - nombor 1 dan 2. Selepas melaksanakan program, nombor 3 akan dipaparkan pada baris arahan. Dalam contoh di atas, kami mempunyai kelas mudah yang hidup sendiri . Tetapi bagaimana jika kelas itu dalam beberapa pakej? Mari kita simulasi situasi berikut: buat direktori src/ru/javarushdan letakkan kelas kita di sana. Sekarang ia kelihatan seperti ini (kami menambah nama pakej pada permulaan fail):
package ru.javarush;

class Calculator {
    public static void main(String[] args){
        int a = Integer.valueOf(args[0]);
        int b = Integer.valueOf(args[1]);

        System.out.println(a + b);
    }
}
Mari kita susun kelas sedemikian dengan arahan berikut:
javac -d bin src/ru/javarush/Calculator.java
Dalam contoh ini, kami menggunakan pilihan pengkompil tambahan -d binyang meletakkan fail yang dikompilasi ke dalam direktori bindengan struktur yang serupa dengan direktori src, tetapi direktori itu binmesti dibuat terlebih dahulu. Teknik ini digunakan untuk mengelakkan kekeliruan fail kod sumber dengan fail bytecode. Sebelum menjalankan program yang disusun, perlu dijelaskan konsepnya classpath. Classpathialah laluan relatif kepada mesin maya akan mencari pakej dan kelas yang disusun. Iaitu, dengan cara ini kami memberitahu mesin maya direktori mana dalam sistem fail adalah akar hierarki pakej Java. Classpathboleh ditentukan apabila memulakan program menggunakan bendera -classpath. Kami melancarkan program menggunakan arahan:
java -classpath ./bin ru.javarush.Calculator 1 2
Dalam contoh ini, kami memerlukan nama penuh kelas, termasuk nama pakej di mana ia berada. Pokok fail akhir kelihatan seperti ini:
├── src
│     └── ru
│          └── javarush
│                  └── Calculator.java
└── bin
      └── ru
           └── javarush
                   └── Calculator.class

4. Pelaksanaan program oleh mesin maya

Jadi, kami melancarkan program bertulis. Tetapi apa yang berlaku apabila program yang disusun dilancarkan oleh mesin maya? Mula-mula, mari kita fikirkan maksud konsep kompilasi dan tafsiran kod. Penyusunan ialah terjemahan program yang ditulis dalam bahasa sumber peringkat tinggi kepada program yang setara dalam bahasa peringkat rendah yang serupa dengan kod mesin. Tafsiran ialah analisis operator demi pernyataan (perintah demi baris, baris demi baris), pemprosesan dan pelaksanaan segera program sumber atau permintaan (berbanding kompilasi, di mana program diterjemahkan tanpa melaksanakannya). Bahasa Java mempunyai kedua-dua pengkompil ( javac) dan penterjemah, iaitu mesin maya yang menukar kod bait kepada kod mesin baris demi baris dan serta-merta melaksanakannya. Oleh itu, apabila kita menjalankan program yang disusun, mesin maya mula mentafsirnya, iaitu, penukaran baris demi baris kod bait kepada kod mesin, serta pelaksanaannya. Malangnya, tafsiran bytecode tulen adalah proses yang agak panjang dan menjadikan java perlahan berbanding pesaingnya. Untuk mengelakkan ini, satu mekanisme telah diperkenalkan untuk mempercepatkan tafsiran bytecode oleh mesin maya. Mekanisme ini dipanggil kompilasi Just-in-time (JITC).

5. Kompilasi Just-in-time (JIT).

Secara ringkasnya, mekanisme kompilasi Just-In-Time adalah ini: jika terdapat bahagian kod dalam atur cara yang dilaksanakan berkali-kali, maka ia boleh disusun sekali ke dalam kod mesin untuk mempercepatkan pelaksanaannya pada masa hadapan. Selepas menyusun bahagian program sedemikian ke dalam kod mesin, dengan setiap panggilan berikutnya ke bahagian program ini, mesin maya akan segera melaksanakan kod mesin yang disusun dan bukannya mentafsirnya, yang secara semula jadi akan mempercepatkan pelaksanaan program. Mempercepatkan program dicapai dengan meningkatkan penggunaan memori (kita perlu menyimpan kod mesin yang disusun di suatu tempat!) dan dengan meningkatkan masa yang dihabiskan untuk penyusunan semasa pelaksanaan program. Penyusunan JIT adalah mekanisme yang agak kompleks, jadi mari kita pergi ke bahagian atas. Terdapat 4 tahap kompilasi JIT kod bait ke dalam kod mesin. Semakin tinggi tahap kompilasi, semakin kompleksnya, tetapi pada masa yang sama pelaksanaan bahagian sedemikian akan lebih cepat daripada bahagian dengan tahap yang lebih rendah. JIT - Pengkompil menentukan tahap kompilasi yang perlu ditetapkan untuk setiap serpihan program berdasarkan kekerapan serpihan itu dilaksanakan. Di bawah tudung, JVM menggunakan 2 pengkompil JIT - C1 dan C2. Pengkompil C1 juga dipanggil pengkompil klien dan mampu menyusun kod hanya sehingga tahap ke-3. Pengkompil C2 bertanggungjawab untuk tahap kompilasi ke-4, paling kompleks dan terpantas.
Menyusun dan melaksanakan aplikasi Java di bawah hud - 3
Daripada perkara di atas, kita boleh menyimpulkan bahawa untuk aplikasi pelanggan mudah, adalah lebih menguntungkan untuk menggunakan pengkompil C1, kerana dalam kes ini adalah penting bagi kita seberapa cepat aplikasi bermula. Aplikasi sisi pelayan yang tahan lama boleh mengambil masa yang lebih lama untuk dimulakan, tetapi pada masa hadapan ia mesti berfungsi dan melaksanakan fungsinya dengan cepat - di sini pengkompil C2 sesuai untuk kita. Apabila menjalankan program Java pada versi x32 JVM, kita boleh secara manual menentukan mod yang ingin kita gunakan menggunakan dan -clientbendera -server. Apabila bendera ini ditentukan, -clientJVM tidak akan melakukan pengoptimuman bytecode yang kompleks, yang akan mempercepatkan masa permulaan aplikasi dan mengurangkan jumlah memori yang digunakan. Apabila menentukan bendera, -serveraplikasi akan mengambil masa yang lebih lama untuk dimulakan kerana pengoptimuman kod bait yang kompleks dan akan menggunakan lebih banyak memori untuk menyimpan kod mesin, tetapi program akan berjalan lebih pantas pada masa hadapan. Dalam versi x64 JVM, bendera -clientdiabaikan dan konfigurasi pelayan aplikasi digunakan secara lalai.

6. Kesimpulan

Ini menyimpulkan gambaran ringkas saya tentang cara menyusun dan melaksanakan aplikasi Java berfungsi. Perkara utama:
  1. Pengkompil javac menukar kod sumber program kepada kod bait yang boleh dilaksanakan pada mana-mana platform di mana mesin maya Java dipasang;
  2. Selepas penyusunan, JVM mentafsir kod bait yang terhasil;
  3. Untuk mempercepatkan aplikasi Java, JVM menggunakan mekanisme kompilasi Just-In-Time yang menukar bahagian program yang paling kerap dilaksanakan kepada kod mesin dan menyimpannya dalam ingatan.
Saya harap artikel ini telah membantu anda mendapatkan pemahaman yang lebih mendalam tentang cara bahasa pengaturcaraan kegemaran kami berfungsi. Terima kasih kerana membaca, kritikan dialu-alukan!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION