linux正確停止java應用進程
在Linux系統下,寫的應用程序,每次重新啟動時,經常會有啟動不成功的情況,困惑了好久。
后來在網上搜索到一篇文章,試了一下,問題解決了。原來的腳本是用kill -9 命令來殺死java應用進程,-9比較暴力,會造成資源釋放不掉的問題。根據文章提示,修改為 -15,問題解決
在linux/unix下,你會怎么中止一個java應用或進程?
多數人可能會回答 kill -9 pid,這是一種在多數情況下正確的做法。不過本文打算闡述使用kill -9帶來的一些問題,并給出另一種標準的kill方式。
標準中斷信號
在Linux信號機制中,存在多種進程中斷信號(Linux信號列表 )。其中比較典型的有 SIGNKILL(9) 和 SIGNTERM(15).
SIGNKILL(9) 和 SIGNTERM(15) 的區別在于:
SIGNKILL(9) 的效果是立即殺死進程. 該信號不能被阻塞, 處理和忽略。
SIGNTERM(15) 的效果是正常退出進程,退出前可以被阻塞或回調處理。并且它是Linux缺省的程序中斷信號。
由此可見,SIGNTERM(15) 才是理論上標準的kill進程信號。
那使用 SIGNKILL(9) 又有什么錯呢?
SIGNKILL(9) 帶來的問題
先看一段程序
Java代碼
/** * Shutdown Hook Presentation * */ public class ShutdownHookTest { private static final void shutdownCallback() { System.out.println("Shutdown callback is invoked."); } public static void main(String[] args) throws InterruptedException { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { shutdownCallback(); } }); Thread.sleep(10000); } } /** * Shutdown Hook Presentation * */ public class ShutdownHookTest { private static final void shutdownCallback() { System.out.println("Shutdown callback is invoked."); } public static void main(String[] args) throws InterruptedException { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { shutdownCallback(); } }); Thread.sleep(10000); } } |
在上面這段程序中,我使用Runtime為當前java進程添加了一個ShutdownHook,它的作用是在java正常退出時,執行shutdownCallback()這個回調方法。
此時,如果你試驗過在java進程未自動退出前,執行 kill -9 pid,即發送 SIGNKILL 信號,會發現這個回調接口是不會被執行的。這是SIGNKILL信號起的作用。
對于我這個簡單的測試用例來說,不被執行也無大礙。但是,如果你的真實系統中有需要在java進程退出后,釋放某些資源。
而這個釋放動作,因為SIGNKILL被忽略了,那就可能造成一些問題。
所以,推薦大家使用標準的kill進程方式,即 kill -15 pid。
posted on 2013-07-08 13:27 順其自然EVO 閱讀(696) 評論(0) 編輯 收藏 所屬分類: linux