2017-08-02 55 views
5

我正在使用一種工具來生成PDF文件,但很不幸100%不可靠。有時這個工具會進入無限循環,並且消耗100%的內存和處理器。使用有限的資源運行bash腳本/程序

我從我的Java應用程序Runtime.getRuntime.exec("command")運行此工具。

  1. 有沒有一種方法可以直接在Java命令中爲此進程設置最大執行時間/內存?
  2. 如果不是直接來自Java,是否有辦法將命令包裝到某些bash工具中,這會限制資源?

我更喜歡命令失敗,而不是利用所有資源並基本上終止服務器。

編輯

基礎上ulimit建議,我想這一點:

Runtime.getRuntime() 
     .exec(arrayOf("bash", "-c", "ulimit -m 2; ulimit -a; pdfprint")) 

我可以看到的ulimit工作:

core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
file size    (blocks, -f) unlimited 
max locked memory  (kbytes, -l) unlimited 
max memory size   (kbytes, -m) 2 
open files      (-n) 10240 
pipe size   (512 bytes, -p) 1 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) 709 
virtual memory   (kbytes, -v) 2 

奇怪的是,我的預期pdfprint崩潰,因爲它沒有足夠的內存。但是,這並沒有發生,程序運行正常。

+0

既然我們談到的bash,我想'command'已經是一個腳本。你不能在調用任何應用程序實際執行PDF的東西之前,在腳本中設置ulimits(數據大小等,堆棧大小等)? – John3136

回答

2

更好的解決方案是編輯你的bash腳本並添加限制。

您可以通過Bash腳本來限制內存使用情況。

限制由kb的內存使用情況(2GB在這個例子中):

ulimit -m 2048000 

極限虛擬內存使用情況:

ulimit -v 2048000 

設置虛擬內存限制是硬限制,這樣的過程將是在超過此限制時死亡:

ulimit -H -v 

對於CPU限制,您可以使用cpulimit工具

+0

這有幫助。我只是困惑,OSX不尊重這些限制,所以它在服務器上工作,但不在我的開發環境中。 –

1

我不知道運行時是否對您是強制性的,但它與java JDK < 5一起使用,之後ProcessBuilder被引入。 使用ProcessBuilder,您可以結合流程waitFor(..)方法。 從java 8中,他們將參數引入此方法。

看起來像(取自原始指南):

boolean waitFor(long timeout, TimeUnit unit) 

造成當前線程等待,如果必要的話,直到通過此處理對象表示的子 已經終止,或在指定 等待時間經過。

下面的僞代碼例子展示它是如何工作:

ProcessBuilder pb = new ProcessBuilder("command"); 
     Process p = pb.start(); 
     p.waitFor(...); 
+0

這並不回答我的問題,因爲waitFor(long)方法甚至在舊方法中。 –