9

Java で奇妙な問題が発生していますProcessBuilder。コードを以下に示します (少し簡略化した形式で)。

public class Whatever implements Runnable
{

public void run(){
        //someIdentifier is a randomly generated string
        String in = someIdentifier + "input.txt";
        String out = someIdentifier + "output.txt";
        ProcessBuilder builder = new ProcessBuilder("./whateveer.sh", in, out);
        try {
            Process process = builder.start();
            process.waitFor();
        } catch (IOException e) {
            log.error("Could not launch process. Command: " + builder.command(), e);
        } catch (InterruptedException ex) {
            log.error(ex);
        }
}

}

what.sh の読み取り:

R --slave --args $1 $2 <whatever1.R >> r.log    

のインスタンスのロードは、固定サイズ (35) の にWhatever送信されます。ExecutorServiceアプリケーションの残りの部分は、CountdownLatch. 次の例外をスローする前に、すべてが数時間 (Scientific Linux 5.0、Java バージョン "1.6.0_24") 正常に実行されます。

java.io.IOException: Cannot run program "./whatever.sh": java.io.IOException: error=11, Resource temporarily unavailable
    at java.lang.ProcessBuilder.start(Unknown Source)
... rest of stack trace omitted...

これが何を意味するのか誰にも分かりますか?の google/bing 検索結果に基づくとjava.io.IOException: error=11、これは最も一般的な例外ではなく、完全に困惑しています。

あまりにも多くのスレッドが同時に同じファイルを起動しようとしているというのは、私のワイルドであまり知識のない推測です。ただし、問題を再現するには数時間の CPU 時間がかかるため、これより少ない数値では試していません。

どんな提案でも大歓迎です。

4

2 に答える 2

8

error=11ほぼ間違いなくEAGAINエラー コードです。

$ grep EAGAIN asm-generic/errno-base.h 
#define EAGAIN      11  /* Try again */

clone(2)システムコールはエラーリターンを文書化しますEAGAIN:

   EAGAIN Too many processes are already running.

fork(2)システム コールは、次の2 つのEAGAINエラーを返します。

   EAGAIN fork() cannot allocate sufficient memory to copy the
          parent's page tables and allocate a task structure for
          the child.

   EAGAIN It was not possible to create a new process because
          the caller's RLIMIT_NPROC resource limit was
          encountered.  To exceed this limit, the process must
          have either the CAP_SYS_ADMIN or the CAP_SYS_RESOURCE
          capability.

本当にメモリが不足している場合は、ほぼ確実にシステム ログに表示されます。dmesg(1)出力を確認するか/var/log/syslog、システム メモリ不足に関する潜在的なメッセージがないか確認します。(他のものは壊れます。これはあまりもっともらしいとは思えません。)

プロセスのユーザーごとの制限またはシステム全体の最大プロセス数のいずれかに達している可能性がはるかに高くなります。プロセスの 1 つがゾンビを適切に取得していない可能性がありますか? ps(1)これは、時間の経過とともに出力を確認することで、非常に簡単に見つけることができます。

while true ; do ps auxw >> ~/processes ; sleep 10 ; done

(実際に問題が発生するまでに数時間かかる場合は、1 分または 10 分ごとに確認してください。)

waitpid(2)ゾンビを刈り取っていない場合は、死んだ子供を刈り取るために使用するために ProcessBuilder に対して行う必要があることについて読んでください。

rlimits で許可されているよりも多くのプロセスを合法的に実行している場合は、スクリプトで ( として実行している場合) を使用するulimitbash(1)、プロパティによりroot高い制限を設定する必要があります。/etc/security/limits.confnproc

システム全体のプロセス制限に達している場合は、より大きな値を に書き込む必要がある場合があります/proc/sys/kernel/pid_maxproc(5)いくつかの (短い) 詳細については、を参照してください。

于 2011-12-05T10:54:15.707 に答える
2

errno 11 は「リソースが一時的に利用できません」を意味します。これは通常、メモリの問題であり、スレッドまたはソケットの作成を妨げる可能性があります。

errno 12 は「メモリを割り当てられません」を意味します。これは、メモリの取得に失敗したことであり、(メモリを必要とするリソースではなく) メモリの直接呼び出しです。

この問題を回避するために、システムのスワップ領域を増やしてみます。

于 2011-12-05T10:46:01.990 に答える