在jvm中增長一個關閉的鉤子,當jvm關閉的時候,會執行系統中已經設置的全部經過方法addShutdownHook添加的鉤子,當系統執行完這些鉤子後,jvm纔會關閉。因此這些鉤子能夠在jvm關閉的時候進行內存清理、對象銷燬等操做。併發
在瞭解關閉鉤子以前,首先介紹一下Runtime.jvm
經過Runtime實例,使得應用程序和其運行環境相鏈接。Runtime是在應用啓動期間自動創建,應用程序不可以建立Runtime,可是咱們能夠經過Runtime.getRuntime()來得到當前應用的Runtime對象引用,經過該引用咱們能夠得到當前運行環境的相關信息,好比空閒內存、最大內存以及爲當前虛擬機添加關閉鉤子(addShutdownHook()),執行指定命令(exec())等等。ide
那麼,什麼叫作jvm關閉呢。繼續google,總結一下以下:google
jvm的關閉方式有三種:操作系統
正常關閉:當最後一個非守護線程結束或者調用了System.exit或者經過其餘特定平臺的方法關閉(發送SIGINT,SIGTERM信號等) 強制關閉:經過調用Runtime.halt方法或者是在操做系統中直接kill(發送SIGKILL信號)掉JVM進程 異常關閉:運行中遇到RuntimeException異常等。線程
關閉鉤子(shutdown hooks)日誌
在某些狀況下,咱們須要在JVM關閉時作些掃尾的工做,好比刪除臨時文件、中止日誌服務以及內存數據寫到磁盤等,爲此JVM提供了關閉鉤子(shutdown hooks)來作這些事情。另外特別注意的是:若是JVM因異常關閉,那麼子線程(Hook本質上也是子線程)將不會中止。但在JVM被強行關閉時,這些線程都會被強行結束。code
關閉鉤子本質是一個線程(也稱爲Hook線程),用來監聽jvm的關閉。經過Runtime的addShutdownHook能夠向JVM註冊一個關閉鉤子。Hook線程在JVM正常關閉纔會執行,強制關閉時不會執行。對象
JVM中註冊的多個關閉鉤子是併發執行的,沒法保證執行順序,當全部Hook線程執行完畢,runFinalizersOnExit爲true,JVM會先運行終結器,而後中止。進程
注意事項:1.hook線程會延遲JVM的關閉時間,因此儘量減小執行時間。
2.關閉鉤子中不要調用system.exit(),會卡主JVM的關閉過程。可是能夠調用Runtime.halt()
3.不能再鉤子中進行鉤子的添加和刪除,會拋IllegalStateException
4.在system.exit()後添加的鉤子無效,由於此時jvm已經關閉了。
5.當JVM收到SIGTERM命令(好比操做系統在關閉時)後,若是鉤子線程在必定時間沒有完成,那麼Hook線程可能在執行過程當中被終止。
6.Hook線程也會拋錯,若未捕獲,則鉤子的執行序列會被中止。
package test; public class TestShutDownHook { public TestShutDownHook() { doShutDownWork(); } private void doShutDownWork() { Runtime run=Runtime.getRuntime();//當前 Java 應用程序相關的運行時對象。 run.addShutdownHook(new Thread(){ //註冊新的虛擬機來關閉鉤子 @Override public void run() { //程序結束時進行的操做 System.out.println("程序結束調用"); } }); } public static void main(String[] args) { new TestShutDownHook(); for (int i = 0; i < 1000; i++) { // 在這裏增添您須要處理代碼 } System.out.println(i); } } }