qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          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

          <2013年7月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 麦盖提县| 石泉县| 镇远县| 龙江县| 石景山区| 鸡泽县| 株洲县| 建瓯市| 梁河县| 霍城县| 新晃| 鸡西市| 灌南县| 砀山县| 浮山县| 望奎县| 山东| 宜州市| 万州区| 莱西市| 西乌| 宜良县| 丹巴县| 乾安县| 密云县| 夏邑县| 梅河口市| 阳西县| 海门市| 吉首市| 隆尧县| 衡山县| 遂溪县| 竹山县| 绥棱县| 石泉县| 阿坝| 鄢陵县| 石河子市| 杭锦旗| 咸宁市|