linux正確停止java應(yīng)用進(jìn)程
在Linux系統(tǒng)下,寫的應(yīng)用程序,每次重新啟動時,經(jīng)常會有啟動不成功的情況,困惑了好久。
后來在網(wǎng)上搜索到一篇文章,試了一下,問題解決了。原來的腳本是用kill -9 命令來殺死java應(yīng)用進(jìn)程,-9比較暴力,會造成資源釋放不掉的問題。根據(jù)文章提示,修改為 -15,問題解決
在linux/unix下,你會怎么中止一個java應(yīng)用或進(jìn)程?
多數(shù)人可能會回答 kill -9 pid,這是一種在多數(shù)情況下正確的做法。不過本文打算闡述使用kill -9帶來的一些問題,并給出另一種標(biāo)準(zhǔn)的kill方式。
標(biāo)準(zhǔn)中斷信號
在Linux信號機制中,存在多種進(jìn)程中斷信號(Linux信號列表 )。其中比較典型的有 SIGNKILL(9) 和 SIGNTERM(15).
SIGNKILL(9) 和 SIGNTERM(15) 的區(qū)別在于:
SIGNKILL(9) 的效果是立即殺死進(jìn)程. 該信號不能被阻塞, 處理和忽略。
SIGNTERM(15) 的效果是正常退出進(jìn)程,退出前可以被阻塞或回調(diào)處理。并且它是Linux缺省的程序中斷信號。
由此可見,SIGNTERM(15) 才是理論上標(biāo)準(zhǔn)的kill進(jìn)程信號。
那使用 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為當(dāng)前java進(jìn)程添加了一個ShutdownHook,它的作用是在java正常退出時,執(zhí)行shutdownCallback()這個回調(diào)方法。
此時,如果你試驗過在java進(jìn)程未自動退出前,執(zhí)行 kill -9 pid,即發(fā)送 SIGNKILL 信號,會發(fā)現(xiàn)這個回調(diào)接口是不會被執(zhí)行的。這是SIGNKILL信號起的作用。
對于我這個簡單的測試用例來說,不被執(zhí)行也無大礙。但是,如果你的真實系統(tǒng)中有需要在java進(jìn)程退出后,釋放某些資源。
而這個釋放動作,因為SIGNKILL被忽略了,那就可能造成一些問題。
所以,推薦大家使用標(biāo)準(zhǔn)的kill進(jìn)程方式,即 kill -15 pid。
posted on 2013-07-08 13:27 順其自然EVO 閱讀(696) 評論(0) 編輯 收藏 所屬分類: linux