使用 kill 命令殺死 java進程,你用對了嗎?
- 2019 年 12 月 10 日
- 筆記
在本地調試agent相關功能,需要經常性的殺掉Java進程,驗證一些極端情況。
每次都是本能執行如下步驟
- jps
- kill -9
- reboot
有一次發現代碼中添加的 ShutdownHook
沒有生效,難道和 kill
命令後面的數字有關?
經過一番查閱,後面的數字代表的是具體信號, kill
命令可將指定的信號發送給相應的進程,linux中常見的信號如下:
- 1 SIGHUP 掛起進程
- 2 SIGINT 終止進程
- 3 SIGGQUIT 停止進程
- 9 SIGKILL 無條件終止進程
- 15 SIGTERM 儘可能終止進程
- 17 SIGSTOP 無條件停止進程,但不是終止
- 18 SIGTSTP 停止或者暫停進程,但不終止進程
- 19 SIGCONT 繼續運行停止的進程
kill
命令默認情況使用15,下面我們驗證下使用不同信號,有什麼不同的表現。
創建一個springBoot應用
啟動類如下,添加了一個鉤子函數,當進程關閉時,將會調用該鉤子函數。
@SpringBootApplication public class Server { public static void main(String[] args) { SpringApplication.run(Server.class); Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { System.out.println("do ShutdownHook.......... "); } }); } }
你可以通過
java -jar ~/project/web/target/demo-1.0.jar
也可以加上nohup + &啟動
nohup java -jar ~/project/web/target/demo-1.0.jar &
通過後者啟動,可以看到啟動所在的目錄多了一個文件nohup.out,該文件記錄了應用啟動運行過程中的日誌。
&表示以後台方式運行應用。但如果退出關閉啟動的控制台,進程將會停止。
nohup + &也是以後台方式運行應用,但是退出關閉啟動的控制台,進程不會停止,且進程日誌將會輸出到nohup.out中。
kill -3
通過執行jps 拿到對應的pid

並執行 kill-35085
,驚奇的發現,Java進程並沒有被殺掉,而是打印了一堆線程信息。

kill -9
上一步的 kill-3
並沒有成功的把進程殺掉,我們繼續使用之前的pid。這次執行 kill-95085

執行完 -9,java進程消失了,只留下這麼一段話。
kill -15
最後,再試試 kill-15
,猶豫Java進程已經被 -9 給kill了,需要重新啟動一次。

這一次,它打印了鉤子函數中的信息,隨之進程也消失了。
總結
kill -3這玩意一般用不到,可以打印當前進程的線程信息,但是不會關閉Java應用!kill -9很暴力,不會調用鉤子函數ShutdownHook。kill也就是kill -15很柔和,將會調用鉤子函數ShutdownHook,一般ShutdownHook中會進行一些操作,比如保存數據,關閉連接等。