使用有限的资源运行bash脚本/程序

时间:2017-08-02 08:14:25

标签: java bash

我正在使用工具生成PDF文件,遗憾的是这不是100%可靠。有时这个工具进入无限循环并消耗100%的内存和处理器。

我正在使用Runtime.getRuntime.exec("command")从我的Java应用程序运行此工具。

  1. 有没有办法直接在Java命令中设置此进程的最大执行时间/内存?
  2. 如果没有直接来自Java,是否有办法将命令包装到某些bash工具中,这会限制资源?
  3. 我更喜欢命令失败而不是利用所有资源并基本上杀死服务器。

    修改

    基于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崩溃,因为它没有足够的内存。但是,这不会发生,程序也能正常运行。

2 个答案:

答案 0 :(得分:2)

更好的解决方案是编辑bash脚本并添加限制。

您可以通过Bash脚本限制内存使用量,执行以下操作。

将内存使用量限制为kb(本例中为2GB):

ulimit -m 2048000

限制虚拟内存使用量:

ulimit -v 2048000

将虚拟内存限制设置为硬限制,以便在超过此限制时终止进程:

ulimit -H -v

对于CPU限制,您可以使用cpulimit工具

答案 1 :(得分:1)

我不知道Runtime是否是强制性的,但是它与java JDK< 5,之后引入了 ProcessBuilder 。 使用ProcessBuilder,您可以结合使用流程waitFor(..)方法。 从java 8开始,他们将参数引入此方法。

看起来(取自原始指南):

boolean waitFor(long timeout, TimeUnit unit)
  

如果需要,使当前线程等待,直到子进程   由此Process对象表示已终止或指定   等待时间过去了。

下面的伪代码示例显示了它的工作原理:

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