フックを使用して JVM を正常にシャットダウンするにはどうすればよいですか?

フックを使用して JVM を正常にシャットダウンするにはどうすればよいですか?

[[390011]]

序文

1. 基本的な概要

プログラムの起動は非常に簡単で、通常は起動時にいくつかのリソースの事前ロードが実行されます。ただし、シャットダウン時に、プリロードされたリソースが起動時に完全にクリーンアップされないことがあるため、フック関数を使用してこれを完了することができます。

2. JVMシャットダウンシナリオの分類

写真を見てみましょう。この写真は CSDN ブログの BarryWang から提供されたもので、ここで説明したいと思います。

上記からわかるように、JVM のシャットダウンは主に 3 つのカテゴリに分かれており、1 つ目は通常のシャットダウン、2 つ目は異常なシャットダウン、3 つ目は強制シャットダウンです。最初の 2 つの方法では、フック関数を使用して正常に閉じることができますが、強制的に閉じる場合はフック関数は機能しません。

これらの概念を念頭に置いて、デモンストレーション用のケースを直接使用し、分析してみましょう。

1. コードデモンストレーションフック関数

1. JVMが正常にシャットダウンする

コードを直接見てみましょう。

  1. パブリッククラステスト{
  2. パブリックボイドスタート(){
  3. Runtime.getRuntime().addShutdownHook(新しいスレッド(()->
  4. System.out.println ( "フック関数が実行されました。ここでリソースを閉じることができます" )
  5. ));
  6. }
  7. 公共 静的void main(String[] args)は例外をスローします{
  8. 新しいテスト().start();
  9. System.out.println ( "メインアプリケーションが実行中です" ) ;
  10. }
  11. }
  12. //コンソール出力
  13. //メインアプリケーションが実行中
  14. //フック関数が実行され、ここでリソースを閉じることができます

コンソール出力を見ると、メインアプリケーションの実行後にフック関数が呼び出され、その後 JVM が正式にシャットダウンされることがわかります。

2. 異常閉鎖

コードのデモを直接見てみましょう。ここでは、異常終了の 2 番目の OOM 状況を示します。まずヒープ サイズを 20M に設定し、コード内に 500M のオブジェクトを作成すると、OOM が発生します。パラメータは -Xmx20M です。

  1. パブリッククラステスト{
  2. パブリックボイドスタート(){
  3. Runtime.getRuntime().addShutdownHook(新しいスレッド(()->
  4. System.out.println ( "フック関数が実行されました。ここでリソースを閉じることができます" )
  5. ));
  6. }
  7. 公共 静的void main(String[] args)は例外をスローします{
  8. 新しいテスト().start();
  9. System.out.println ( "メインアプリケーションが実行中です" ) ;
  10. ランタイムを取得します。
  11. バイト[] b = 新しいバイト[500*1024*1024];
  12. }
  13. }
  14. //コンソール出力
  15. //メインアプリケーションが実行中
  16. //フック関数が実行され、ここでリソースを閉じることができます

コンソールから、異常終了した場合でもフック関数が呼び出されることがわかります。

3. 強制終了

ここでは、Runtime.getRuntime().halt() を使用して、強力なシャットダウンを示します。このメソッドと System.exit の違いは、System.exit はフック関数を実行しますが、Runtime.getRuntime().halt() は実行しないことです。

  1. パブリッククラステスト{
  2. パブリックボイドスタート(){
  3. Runtime.getRuntime().addShutdownHook(新しいスレッド(()->
  4. System.out.println ( "フック関数が実行されました。ここでリソースを閉じることができます" )
  5. ));
  6. }
  7. 公共 静的void main(String[] args)は例外をスローします{
  8. 新しいテスト().start();
  9. System.out.println ( "メインアプリケーションが実行中です" ) ;
  10. ランタイムを取得します。
  11. }
  12. }
  13. //コンソール出力
  14. //メインアプリケーションが実行中

上記のコードの出力から、Runtime.getRuntime().halt(1) を呼び出すと JVM が強制的にシャットダウンされ、フック関数は実行される前にシャットダウンされることがわかります。ただし、System.exit を使用すると、引き続き実行されます。したがって、JVM をシャットダウンするには通常、System.exit が使用されます。

4.フック機能を削除する

上記はフック関数の役割を示しています。簡単に取り外せる場合もあります。

  1. パブリッククラステスト{
  2. 公共 静的void main(String[] args)は例外をスローします{
  3. //新しいTest().start();
  4. スレッド willNotRun = new Thread(() ->
  5. システム。 out .println( "実行されません!" ));
  6. Runtime.getRuntime().addShutdownHook(willNotRun);
  7. System.out.println ( "メインアプリケーションが実行中です" ) ;
  8. Runtime.getRuntime().removeShutdownHook(willNotRun);
  9. }
  10. }
  11. //コンソール出力
  12. //メインアプリケーションが実行中

さて、フック関数の基本的な動作はここに書かれています。使い方は比較的簡単です。しかし、以前に Spring の起動プロセスを見たことがあるのですが、その起動プロセスをもう一度見てみると、フック関数も使用されていることがわかりました。

2. 典型的なアプリケーションシナリオ

1. Springを使用する

Spring がコンテキストを閉じるときに、フック関数を使用して残りのリソースを閉じることができます。この方法は、ApplicationContext を使用してフック関数を登録することです。

  1. ApplicationContext.registerShutdownHook();
  2. //上記のコードは分析して見ることができます
  3. パブリックvoid registerShutdownHook() {
  4. this.shutdownHook がnull場合
  5. this.shutdownHook = 新しいスレッド() {
  6. @オーバーライド
  7. パブリックボイド実行(){
  8. //スプリングは正常に閉じます
  9. クローズ();
  10. }
  11. };
  12. //残りのリソースを閉じるためのフック関数を呼び出す
  13. Runtime.getRuntime().addShutdownHook(this.shutdownHook);
  14. }
  15. }

ソース コードからわかるように、Spring は実際にシャットダウンするために Java のフック関数を呼び出します。

2. その他の用途

多くのブログで、Spark と Hadoop のシャットダウンも目にしました。ソースコードを読んでいないので、ここでは結論を述べます。その他の使用シナリオでは、基本的に Java フック関数が呼び出されて実行されます。

結論は

JVM をシャットダウンするときに、フック関数をカプセル化してスレッドを正常にシャットダウンすることができます。ただし、使用時には以下の点に注意する必要があります。

1. フック関数は本質的にはスレッドである

複数のフックが同時に実行され、JVM はそれらの実行順序を保証しません。したがって、一連の操作を 1 つのフックで実行するのが最適です。

2. フック内に新しいフックを作成できなくなりました

シャットダウン フックでは、フックの登録や削除などの操作を実行することはできません。そうしないと、JVM によって IllegalStateException がスローされます。 System.exit() も使用できません。前述のように、System.exit() はフック関数の実行をトリガーしますが、Runtime.halt() はシャットダウンを強制できるため、Runtime.halt() でも実行できます。

3. フックには時間のかかる操作を入れないのがベスト

フック関数は主に残りのリソースを閉じるために使用されるため、時間のかかる操作は実行しないでください。

はい、とりあえずここでやめておきます。

この記事はWeChat公式アカウント「Yugong Yaoyishan」から転載したものです。下のQRコードからフォローできます。この記事を転載する場合は、Yugongyaoyishanの公式アカウントまでご連絡ください。

<<:  新しいテクノロジートレンド: SaaS セキュリティ構成管理 (SSPM)

>>:  4 Windows 仮想デスクトップ管理の制限

推薦する

Jakarta EE 10 のクラウドネイティブ時代を理解する

ご存知のとおり、Go と Rust はクラウド ネイティブの主要な開発言語となっています。 Rust...

hmbcoudハーフムーンベイ-ジャパンcn2 vpsの簡単な評価、高品質のネットワーク、コスト効率

Half Moon Bay(hmbcoud)の常連VPSホストcatはすでに米国の3ネットワークcn...

ウェブサイトがリストに載っていないのは検索エンジンに関係しているとすぐに確認できないのはなぜですか?

多くの新参者や初心者ウェブマスターは、新しいウェブサイトを最適化する際に、自分のウェブサイトが組み込...

サイトページを最適化するにはどうすればいいですか?

優れたウェブサイトは、最終的なランディング ページを通じてユーザーに役立つ情報を提供する必要がありま...

dmit: 月額 19 ドル、1.2T トラフィック、香港データセンター、香港 VPS は CN2 回線を使用

dmit 香港データセンターは、CN2 GT 回線と、中国聯通および中国移動の香港 PCCW への直...

ヘッツナーはどうですか? フィンランドのデータセンターのクラウドサーバーのレビュー(フィンランド)

ヘッツナーはどうですか?ヘッツナーフィンランドはいかがでしょうか?現在、Hetzner はヨーロッパ...

APPマーケティングの3つのポイントであるポジショニング、品質、プロモーション

携帯電話、タブレット、ソーシャルメディアをよく使う友人は、アプリをよく知っているはずです。アプリは、...

ウェブサイトのビジュアルデザイン: ウェブページのカラーマッチングの自然なスタイル

この記事には細かいことは何も書かれていません。ただテクニックを共有しているだけです。とてもシンプルで...

Adobe Experience Cloud が中国で開始、Adobe、Microsoft、21Vianet が三者協力を祝う

2018年4月11日、Adobe、Microsoft、21Vianetの上級幹部が集まり、中国本土市...

ビッグデータマーケティング:企業が注目すべき小さな領域

インターネット時代はビッグデータの時代でもあります。多くの人がオンラインマーケティングを利用していま...

buyvm マイアミデータセンター VPS 国内初評価、高性能プラットフォーム: AMD Ryzen 9 3900x+DDR4+NVMe+1Gbps 帯域幅無制限トラフィック

buyvm の 4 番目のデータ センターは、米国南東海岸のマイアミにあり、オンラインになっています...

ピークサーバー - $10/年/256M メモリ/10G ハードディスク/500G トラフィック/IP あたり $0.1

ピークサーバーからの最新ニュースによると、公式は当初の生涯50%割引をキャンセルしましたが、それでも...

この IT テストは「冷や水を浴びせる」ほどの勇気があります。クラウド コンピューティングの「トップ 10 の課題」が新たに公開されましたが、1 位は誰でしょうか?

クラウド コンピューティングには数多くの困難な課題があります。現在、多くの企業がクラウドに移行してい...

Hostus-3.5 USD/KVM/512 MB RAM/15 GB HDD/750 GB Flow/ロサンゼルス/Windows

Hostus は、KVM VPS の新バージョンを正式にリリースしました。今回、Hostus の K...