34

To speed up the startup time of the JVM, the Sun developers decided it is a good idea to precompile the standard runtime classes for a platform during installation of the JVM. These precompiled classes can be found e.g. at:

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

My company currently develops a Java standalone application which brings its own JRE, so it would be a fantastic option to speed up our application start time by adding our own application classes to this jsa file, too.

I don't believe the JSA file was created by magic, so: How is it created? And how can I trick the JVM into incorporating my own classes?

EDIT: I already found out the following:

The classes.jsa is created by the command

java -Xshare:dump

The list of classes to incorporate in the dump can be found in $JAVA_HOME/jre/lib/classlist.

I even managed to add my own classes here (and to add them into the rt.jar for java to find them), and to generate my own checksum below the classlist file.

The final problem is: Only classes in the packages java, com.sun, and org.w3c seem to be recognized, if I leave the same classes in their original packages, they won't be loaded. I searched the whole OpenJDK source for pointer about this, but it seems to have something to do with protection domains. If someone is interested enough in this topic and knowledgeable enough, please add some pointers for me to investigaete further.

4

4 に答える 4

11

Java 8u40 (および Embedded Java 8u51) の時点で、Java は Application Class Data Sharing (AppCDS) (つまり、共有アーカイブ内の独自のクラス) をサポートするようになりました。私たちの組み込み Java では、起動時の改善が 40% を超えていることがわかりました。私たちの側でほとんど作業を行わないのはかなり素晴らしいです...

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

于 2015-10-21T13:52:54.053 に答える
11

あなたはほとんどそこにいました.それを機能させるために必要なのは、いくつかのステップだけです. 独自のクラスを client.js に追加するには、次の手順が必要です。

  1. あなたのクラスの修飾名 (あなたが持っています)

  2. これらのクラスのクラスパス (あなたが持っています)

  3. チェックサムを再計算する方法を知っている(持っている)

  4. Java クラスを使用して現在プリコンパイルしているクラスのクラスパスを指定して、新しいファイルをダンプします。

  5. 新しい classes.jsa のダンプに使用したのと同じクラスパスを指定して、プログラムを実行します。

クラスリストに追加するクラスのクラスパスを指定するには、-Xbootclasspath/aコマンドを使用します。JVM がブート クラスがある場所を検索するときに、ディレクトリ/JAR を追加します。classes.jsa のデフォルトのスペースは非常に小さいため、改善する必要がある場合はコマンド-XX:SharedReadWriteSize-XX:SharedReadOnlySizeコマンドを使用できます。ダンプ コマンドは次のようになります。

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

最後のステップは、共有モードをオンにしたことを思い出して、Java アプリケーションを通常どおり実行することです。Xbootclasspathダンプに追加したように、excatlyも追加する必要があります。これは次のようになります。

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

これで、クラスリストに追加したすべてのクラスが、同じ JVM で実行されている他のインスタンスと共有されます。

于 2013-01-29T18:39:20.943 に答える
8

興味深いアイデアです。私が読んだように、VM間でデータを共有し、コンパイルではなくクラスロードを高速化するために使用されています。どの程度のブーストが得られるかはわかりませんが、起動時にすでに大きなラグがある場合は、試してみる価値があるかもしれません (ただし、VM は既にそれを緩和しようとしています)。

自分で試してみると、このファイルは通常、Sun VM のインストール時に作成されるようですが、制御することもできます。一部の詳細は、この古い Sun Java 5クラス データ共有ドキュメントに記載されています (既にご覧になっているかもしれません)。一部の Sun Java 6 のドキュメントでも数回言及されていますが、ドキュメントにはあまり追加されていません。元々はIBM VM の機能だったようです。そして、リンク ダンプを続けるために、この記事で少し説明します。

私は個人的にそれについてあまり知らないので、あなたがそれをどのように制御できるかわかりません. 再生成することはできますが、カスタムのものを入れることを意図しているとは思いません。また、「だます」ことができたとしても、おそらくある種の Sun/Oracle ライセンスに違反することになります (たとえば、rt.jar をいじって再配布することはできません)。とはいえ、アプリに数千または数万のクラスがなければ、起動時間が大幅に改善されるとは思えません。

(そして、これは実際には答えではありませんが、大きすぎてコメントに収まりませんでした。質問が興味深いと思ったので、少し調査して、誰かが同じ情報を役に立つと思った場合に備えて、ここにリンクを置きました。)

于 2011-01-14T16:54:34.023 に答える