2016-04-11 58 views
1

我有一個通過Spring JMSListener啓動的進程。該過程基本上運行一個運行時exe文件來調用imagemagick來對圖像進行一些重新處理。在* nix下,即使Runtime exec命令以退出碼0退出並且不引發異常,仍有線程保留。該應用程序正在使用Gythio Runtime Exec類來執行其工作。由於運行時可能出現的StdErr和StdOut通常存在的缺陷,Gythio正在正確處理,所以即使它成功了,我們也不應該摧毀這個過程嗎?如果進程以退出代碼0結束,我應該調用Process.destroy()嗎?

下面是一個簡單的例子,請忽略代碼錯誤,它不是真正的代碼。我的問題是//過程中完成的塊周圍:

public class Test { 

    public void doSomething(String cmd, String processProperties, String processDirectory){ 

     try { 
      // cmd is something like convert ... file .. params 

      Runtime runtime = Runtime.getRuntime(); 

      final Process process = runtime.exec(cmd, processProperties, processDirectory); 

      int exitValue = process.waitFor(); 

      System.out.println("exit value: " + exitValue); 
      BufferedReader buf = new BufferedReader(new InputStreamReader(
        process.getInputStream())); 
      String line = ""; 
      while ((line = buf.readLine()) != null) { 
       System.out.println("exec response: " + line); 
       //log = line; 
       //writeToFile(line); 
      } 
      // process is done... should it be destroyed? 
      if(process != null){ 
       process.destroy(); 
      } 
      // end process done 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
    } 
} 

約一小時的運行後,在Tomcat中運行的應用程序顯示這些線程(Tomcat所在PID 1641):

[[email protected] logs]# top -H -p 1641 
top - 19:45:24 up 264 days, 10:33,  4 users,  load average: 0.00, 0.00, 0.19 
Tasks: 5068 total,   0 running, 5068 sleeping,   0 stopped,   0 zombie 
Cpu(s):  0.7%us,  1.5%sy,  0.0%ni, 97.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st 
Mem:   8061332k total,  6690912k used,  1370420k free,   195348k buffers 
Swap:  1888252k total,    77672k used,  1810580k free,  5070148k cached 

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND 
1734 adminuser  20   0 5842m 948m  13m S  0.3 12.0   3:03.41 java 
1641 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.00 java 
1643 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:01.20 java 
1644 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:02.31 java 
1671 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:02.28 java 
1678 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:02.35 java 
1686 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:02.20 java 
1687 adminuser  20   0 5842m 948m  13m S  0.0 12.0   2:25.66 java 
1688 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.11 java 
1691 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.08 java 
1706 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.00 java 
1712 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:53.24 java 
1720 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:39.38 java 
1721 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:12.96 java 
1722 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.00 java 
1723 adminuser  20   0 5842m 948m  13m S  0.0 12.0   2:54.47 java 
1724 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.00 java 
1728 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:03.62 java 
1729 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:08.16 java 
1731 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.75 java 
1732 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:02.58 java 
1735 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:03.63 java 
1736 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:02.23 java 
1737 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:00.92 java 
1738 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:03.59 java 
1739 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:02.96 java 
1740 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:05.07 java 
1741 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:02.26 java 
1742 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:04.57 java 
1743 adminuser  20   0 5842m 948m  13m S  0.0 12.0   3:01.79 java 
1744 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:26.27 java 
1745 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.10 java 
1746 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:10.72 java 
1747 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.00 java 
1748 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:10.99 java 
5611 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.68 java 
5620 adminuser  20   0 5842m 948m  13m S  0.0 12.0   0:00.36 java 

任何/所有的答覆表示讚賞!提前致謝!

+1

如果關閉流(例如,使用try-with-resources),它們是否被清除? –

+1

你不會認爲這是必要的。你會想如果進程已經返回了一個退出代碼,它已經調用exit()或者退出了main,所以沒有進程可以銷燬。 – EJP

+0

程序無法退出(或返回退出代碼),直到程序結束並且程序關閉。 –

回答

0

我懷疑你的程序正在創建一個不平凡的輸出。當你在後臺運行一個程序時,它會寫出可能只有幾KB的緩衝區大小。一旦達到緩衝區大小,它就等待用戶(你的程序)讀取輸出。這適用於標準輸出和錯誤。

如果您不消耗輸出和錯誤,您的衍生程序可能會永遠等待,但您首先等待退出代碼不會發生,這樣就會發生死鎖。

我建議你使用ProcessBuilder,將錯誤重定向到輸出,並在等待退出代碼之前將其讀到最後。

從示例中。

ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2"); 
pb.redirectErrorStream(true); 
File log = new File("log"); 
pb.redirectOutput(Redirect.appendTo(log)); 
Process p = pb.start(); 
// no need to copy the output 
int exit = p.waitFor(); 
+0

該示例僅僅是爲了說明我認爲類https://github.com/Alfresco/gytheio/blob/master/gytheio-commons/src/main/java/org/gytheio/util/exec/RuntimeExec.java可能需要一個process.destroy()。如果你看看這個類,這個lib會消耗掉標準錯誤,所以我不這麼認爲。我傾向於同意@EJP上面的評論。雖然謝謝! – Griff

+0

@Griff代碼與您問題中的代碼非常不同。 –