Pertanyaan Percepat permulaan aplikasi dengan menambahkan kelas aplikasi sendiri ke classes.jsa


Untuk mempercepat waktu startup dari JVM, pengembang Sun memutuskan bahwa adalah ide yang baik untuk mengkompilasi kelas runtime standar untuk platform selama instalasi JVM. Kelas yang dikompilasi ini dapat ditemukan misalnya di:

$ JAVA_HOME \ jre \ bin \ client \ classes.jsa

Perusahaan saya saat ini mengembangkan aplikasi mandiri Java yang membawa JRE-nya sendiri, sehingga akan menjadi opsi yang fantastis untuk mempercepat waktu mulai aplikasi kami dengan menambahkan kelas aplikasi kami sendiri ke file jsa ini juga.

Saya tidak percaya file JSA dibuat oleh sihir, jadi: Bagaimana cara membuatnya? Dan bagaimana saya bisa mengelabui JVM ke dalam menggabungkan kelas saya sendiri?

EDIT: Saya sudah menemukan yang berikut:

Class.jsa dibuat oleh perintah

java -Xshare:dump

Daftar kelas untuk dimasukkan dalam dump dapat ditemukan di $JAVA_HOME/jre/lib/classlist.

Saya bahkan berhasil menambahkan kelas saya sendiri di sini (dan menambahkannya ke rt.jar untuk java untuk menemukannya), dan untuk menghasilkan checksum saya sendiri di bawah file daftar kelas.

Masalah terakhir adalah: Hanya kelas dalam paket java, com.sun, dan org.w3c yang tampaknya diakui, jika saya meninggalkan kelas yang sama dalam paket aslinya, mereka tidak akan dimuat. Saya mencari seluruh sumber OpenJDK untuk pointer tentang ini, tetapi tampaknya ada hubungannya dengan domain perlindungan. Jika seseorang cukup tertarik dengan topik ini dan cukup berpengetahuan, harap tambahkan beberapa petunjuk bagi saya untuk melakukan investasi lebih lanjut.


32
2018-01-14 14:29


asal


Jawaban:


Seperti Java 8u40 (dan Embedded Java 8u51), Java sekarang mendukung Application Class Data Sharing (AppCDS) (yaitu kelas Anda sendiri dalam arsip bersama). Pada java kami yang disematkan, kami telah menemukan peningkatan startup> 40%! Cukup mengagumkan karena hampir tidak ada kerja di pihak kami ...

https://blogs.oracle.com/thejavatutorials/entry/jdk_8u40_released


10
2017-10-21 13:52



Anda hampir sampai, Anda hanya perlu beberapa langkah untuk membuatnya berfungsi. Untuk menambahkan kelas Anda sendiri ke klien. Anda memerlukan langkah-langkah berikut:

  1. Nama yang memenuhi syarat kelas Anda (Anda memilikinya)

  2. Classpath dari kelas-kelas ini (Anda memilikinya)

  3. Ketahui cara menghitung ulang checksum (Anda memilikinya)

  4. Dump file baru, menyediakan classpath dari kelas yang sekarang Anda lakukan dengan kelas Java.

  5. Jalankan program, berikan jalur kelas yang sama dengan yang Anda gunakan untuk membuang kelas-kelas baru.jsa

Untuk menyediakan classpath di mana kelas-kelas yang Anda tambahkan ke daftar kelas, gunakan -Xbootclasspath/a perintah. Ini akan menambahkan direktori / JARs ketika JVM mencari tempat di mana kelas boot. Ruang default untuk class.jsa sangat kecil, jika Anda perlu memperbaikinya Anda dapat menggunakan -XX:SharedReadWriteSize dan -XX:SharedReadOnlySize perintah. Perintah dump Anda Anda terlihat mirip dengan ini:

java -Xshare:dump -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

Langkah terakhir adalah jalankan aplikasi java secara normal, ingatlah untuk mengaktifkan mode share. Anda juga perlu menambahkan Xbootclasspath excatly saat Anda menambahkan di dump. Ini akan terlihat mirip dengan ini:

java myapp.java -Xshare:on -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar;

Sekarang setiap kelas yang Anda masukkan pada daftar kelas sedang dibagikan dengan contoh lain yang berjalan di JVM yang sama.


11
2018-01-29 18:39



Ide yang menarik. Saat saya membacanya, itu digunakan untuk berbagi data di seluruh VM dan untuk mempercepat classloading, bukan kompilasi. Saya tidak yakin berapa banyak peningkatan yang akan Anda dapatkan, tetapi mungkin patut dicoba jika Anda memiliki lag yang besar saat startup (meskipun VM sudah mencoba untuk menguranginya).

Untuk mencoba sendiri, tampaknya file ini biasanya dibuat ketika Sun VM diinstal, tetapi Anda juga dapat mengendalikannya. Beberapa detail ada di Java Sun yang lebih tua ini 5 Pembagian Data Kelas dokumen (yang mungkin sudah Anda lihat?). Beberapa dokumen Sun Java 6 juga menyebutkannya beberapa kali, tetapi jangan tambahkan banyak ke dokumentasi. Tampaknya itu awalnya sebuah Fitur VM IBM. Dan, untuk melanjutkan dump tautan, itu dijelaskan sedikit dalam artikel ini.

Saya pribadi tidak tahu banyak tentang itu, jadi saya tidak tahu bagaimana Anda mengendalikannya. Anda dapat meregenerasinya, tapi saya tidak berpikir itu dimaksudkan agar Anda memasukkan barang-barang khusus. Juga, bahkan jika Anda dapat "mengelabui" itu, itu mungkin akan melanggar lisensi Sun / Oracle dari beberapa macam (Anda tidak dapat mengacaukan rt.jar dan mendistribusikan ulang, misalnya). Dan, semua yang dikatakan, saya ragu Anda akan melihat peningkatan serius dalam waktu startup kecuali Anda memiliki ribuan atau puluhan ribu kelas di aplikasi Anda?

(Dan ini tidak benar-benar jawaban, saya tahu, tapi itu terlalu besar untuk dimasukkan dalam komentar, dan saya menemukan pertanyaan yang menarik sehingga saya menyelidiki sedikit dan meletakkan tautan di sini jika ada yang menemukan info yang sama berguna.)


8
2018-01-14 16:54



Butuh sedikit mencari tahu tapi saya punya 4 Java8 VMs (versi 1.8.0_162) berjalan menggunakan kelas bersama. Skrip berikut digunakan untuk menyiapkan dan menguji berbagi dan dengan sedikit modifikasi dapat digunakan di tempat lain:

#!/bin/bash

# Libraries to load
LIBS1="./lib/protobuf-java-2.6.1.jar:\
./lib/jetty-server-9.2.18.v20160721.jar:./lib/jetty-util-9.2.18.v20160721.jar:./lib/servlet-api-3.1.jar:./lib/jetty-http-9.2.18.v20160721.jar:./lib/jetty-io-9.2.18.v20160721.jar:\
./lib/derby.jar:\
./lib/json-simple-1.1.1.jar:"
LIBS2=":./lib/GTFS.jar"

# Uncomment these lines for the first phase where you are determining the classes to archive. During this phase aim to get as many classes loaded as possible
# which means loading a schedule and retrieving the stop list and next vehicle information
#
#APPCDS="-Xshare:off -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:DumpLoadedClassList=../GtfsAppCds.lst"
#java -Xmx512m $APPCDS -Dderby.system.home=database -classpath $LIBS1$LIBS2 com.transitrtd.GtfsOperatorManager

# Uncomment these lines when the class list is created and run to create the shared archive. Classes marked as unverifiable will need to be removed from the
# archived class list in GtfsAppCds.lst and the lines below run again. LIBS2 above contains jars which are left out of the archive. These are jars which change
# frequently and would therefore cause the archive to be frequently rebuilt.
#                                                                                                                                                                                                               
#APPCDS="-Xshare:dump -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:SharedClassListFile=../GtfsAppCds.lst -XX:SharedArchiveFile=../GtfsAppCds.jsa"
#java -Xmx512m $APPCDS -classpath $LIBS1

# Uncomment these lines when wishing to verify the application is using the shared archive.
#
#APPCDS="-Xshare:on -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -XX:SharedArchiveFile=../GtfsAppCds.jsa -verbose:class"
#java -Xmx512m $APPCDS -Dderby.system.home=database -classpath $LIBS1$LIBS2 com.transitrtd.GtfsOperatorManager

Perhatikan bahwa file arsip bersama (yaitu file jsa) bergantung pada arsitektur dan perlu dibuat pada setiap jenis platform target.

Juga jika sebuah guci menggunakan paket yang disegel, pengecualian keamanan dibuang, lihat

https://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html 

untuk informasi tentang paket yang disegel. Ini adalah kasus di atas dengan derby.jar tapi masalahnya bisa diselesaikan dengan membongkar file jar, mengganti Disegel: benar dengan Disegel: salah di manifes dan mengemasnya kembali.

guci yang dibuat dengan java versi lama tidak dapat digunakan dalam arsip bersama, dalam kasus di atas versi derby harus ditingkatkan dari 10.10 menjadi 10.14 untuk mendapatkan keuntungan.


0
2018-04-18 15:09