使用 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中會進行一些操作,比如保存數據,關閉連接等。