2017-08-02 56 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)方法甚至在旧方法中。 –