JVM を再起動する方法はありますか? 実際に終了するのではなく、すべてのクラスを閉じてリロードし、メインを上から実行しますか?
8 に答える
あなたの最善の策は、おそらくループ内で Java インタープリターを実行し、そのまま終了することです。例えば:
#!/bin/sh
while true
do
java MainClass
done
完全に再起動またはシャットダウンする機能が必要な場合は、終了ステータスをテストできます。
#!/bin/sh
STATUS=0
while [ $STATUS -eq 0 ]
do
java MainClass
STATUS=$?
done
Java プログラム内では、System.exit(0) を使用して「再起動」することを示し、System.exit(1) を使用して停止して停止したままにすることを示すことができます。
IBM の JVM には「リセット可能」と呼ばれる機能があり、これを使用すると、求めていることを効果的に行うことができます。
IBM JVM 以外では不可能だと思います。
実際の「再起動」ではありませんが、次のようになります。
独自のクラスローダーを構築し、それを使用してすべてのクラス(ブートストラップを除く)をロードできます。次に、「再起動」する場合は、次のことを確認してください。
- 開いてクラスを使用しているスレッドをすべて終了します。
- 作成したウィンドウ/ダイアログ/アプレット(UIアプリケーション)を破棄します。
- 他のGCルート/OSリソースを必要とするピアリソース(データベース接続など)を閉じる/破棄します。
- カスタマイズしたクラスローダーを破棄し、その別のインスタンスを作成して、すべてのクラスをリロードします。おそらく、ファイルからクラスを前処理することでこのステップを最適化できるため、コードベースに再度アクセスする必要はありません。
- 主要な入り口に電話してください。
この手順は、WebサーバーでWebアプリケーションを「ホットスワップ」するときに(ある程度)使用されます。
ただし、静的クラスメンバーとJVM「グローバル」オブジェクト(制御下にないGCルートによってアクセスされるオブジェクト)は残ります。たとえば、Locale.setLocale()は、ロケールの静的メンバーに影響を与えます。Localeクラスはシステムクラスローダーによってロードされるため、「再起動」されません。つまり、Locale.setLocale()で使用されていた古いLocaleオブジェクトは、明示的にクリーンアップされていない場合、後で使用できるようになります。
さらに別の方法は、クラスのインストルメンテーションです。しかし、私はそれについてほとんど知らないので、アドバイスを提供することを躊躇します。
アプリケーション サーバーで作業している場合、それらには通常、再デプロイ時にアプリケーション (Web アプリ、エンタープライズ アプリ) 内のすべてのクラスをリロードするホット デプロイ メカニズムが組み込まれています。
それ以外の場合は、商用ソリューションを検討する必要があります。Java Rebel ( http://www.zeroturnaround.com/javarebel/ ) は、そのようなオプションの 1 つです。
JavaX では簡単です。標準関数nohupJavax()またはrestart()を使用できます。
私の知る限り、そのような方法はありません。
それを行う方法があった場合、正常な再起動を提供するために保持されているすべてのリソースを適切に解放するには、現在ロードされているコードに大きく依存することに注意してください (ファイル、ソケット/tcp/http/データベース接続、スレッドなどについて考えてください)。 )。
Jboss AS などの一部のアプリケーションは、コンソールで Ctrl+C をキャプチャし、正常なシャットダウンを提供してすべてのリソースを閉じますが、これはアプリケーション固有のコードであり、JVM 機能ではありません。
JMX を使用して同様のことを行います。JMX を使用してモジュールを「アンロード」してから「再ロード」します。舞台裏では、別のクラスローダーを使用していると確信しています。