使用 kill 命令殺死 java進程,你用對了嗎?


在本地調試agent相關功能,需要經常性的殺掉Java進程,驗證一些極端情況。

每次都是本能執行如下步驟

  • jps
  • kill -9 <pid>
  • 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);
    <span class="token class-name">Runtime</span><span class="token punctuation">.</span><span class="token function">getRuntime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addShutdownHook</span><span class="token punctuation">(</span><span class="token keyword"><span class="hljs-keyword"><span class="hljs-keyword"><span class="hljs-keyword">new</span></span></span></span> <span class="token class-name">Thread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token annotation punctuation"><span class="hljs-meta"><span class="hljs-meta"><span class="hljs-meta">@Override</span></span></span></span>
        <span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span><span class="token keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span><span class="token function"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">run</span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">(</span></span></span></span></span></span></span><span class="token punctuation"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params"><span class="hljs-function"><span class="hljs-params">)</span></span></span></span></span></span></span><span class="hljs-function"><span class="hljs-function"><span class="hljs-function"> </span></span></span><span class="token punctuation">{</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string">"do ShutdownHook.......... "</span></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

你可以通過

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 -3 5085,驚奇的發現,Java進程並沒有被殺掉,而是打印了一堆線程信息。

kill -9

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

執行完 -9,java進程消失了,只留下這么一段話。

kill -15

最后,再試試 kill -15,猶豫Java進程已經被 -9 給kill了,需要重新啟動一次。

這一次,它打印了鈎子函數中的信息,隨之進程也消失了。

總結

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

原文地址:https://www.jianshu.com/p/77ca821e7151


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM