21

私はタイトルエラーを取得しています:

mcfork(): Unable to fork: Cannot allocate memory

mcapply で関数を実行しようとした後top、51% であると表示されます

これは EC2 インスタンスにありますが、最新の R を持っています。

他に何がこのエラーを引き起こす可能性があるか知っている人はいますか?

ありがとう、

-N

4

5 に答える 5

5

R 関数mcforkは syscall のラッパーにすぎませんfork(ちなみに、man ページには、この呼び出し自体が のラッパーであると書かれていますclone)

forkの動作をテストするための簡単な C++ プログラムを作成しました。

#include <stdio.h>
#include <unistd.h>

#include<vector>

int main(int argc, char **argv)
{
    printf("--beginning of program\n");

    std::vector<std::vector<int> > l(50000, std::vector<int>(50000, 0));

//    while (true) {}

    int counter = 0;
    pid_t pid = fork();
    pid = fork();
    pid = fork();


    if (pid == 0)
    {
        // child process
        int i = 0;
        for (; i < 5; ++i)
        {
            printf("child process: counter=%d\n", ++counter);
        }
    }
    else if (pid > 0)
    {
        // parent process
        int j = 0;
        for (; j < 5; ++j)
        {
            printf("parent process: counter=%d\n", ++counter);
        }
    }
    else
    {
        // fork failed
        printf("fork() failed!\n");
        return 1;
    }

    printf("--end of program--\n");
    while (true) {}
    return 0;
}

まず、プログラムは約 8GB のデータをヒープに割り当てます。次に、fork 呼び出しを介して 2^2^2 = 8 個の子を生成し、ユーザーによって強制終了されるのを待機し、タスク マネージャーで簡単に見つけられるように無限ループに入ります。

ここに私の観察があります:

  1. fork が成功するには、システムに少なくとも 51% の空きメモリが必要ですが、これには swapが含まれます。/proc/sys/vm/overcommit_*これは、 proc ファイルを編集することで変更できます。
  2. 予想どおり、これ以上メモリを消費する子はいないため、この 51% の空きメモリはプログラム全体で空きのままであり、後続のフォークもすべて失敗しません。
  3. メモリはフォーク間で共有されるため、最後の子を殺した後にのみ回収されます。

メモリの断片化の問題

fork に関するメモリ断片化の層について心配する必要はありません。fork は仮想メモリ上で動作するため、R のメモリ断片化はここでは適用されません。物理メモリの断片化について心配する必要はありません。事実上、最新のオペレーティング システムはすべて仮想メモリを使用するためです (その結果、スワップを使用できるようになります)。問題になる可能性がある唯一のメモリの断片化は、仮想メモリ空​​間の断片化ですが、Linux の仮想メモリ空​​間での AFAIK は 2^47 であり、これは巨大ではありません。実用的なサイズ。

概要:

物理メモリよりも多くのスワップがあることを確認してください。計算がRAMにあるよりも多くのメモリを実際に必要としない限り、必要なだけmcforkそれらを実行できます。

または、システム全体の安定性 (メモリ不足) の危険を冒しても構わない場合は、echo 1 >/proc/sys/vm/overcommit_memoryLinux で root として試してください。

またはさらに良い:(より安全)

echo 2 >/proc/sys/vm/overcommit_memory
echo 100 >/proc/sys/vm/overcommit_ratio

オーバーコミットについて詳しくは、https ://www.win.tue.nl/~aeb/linux/lk/lk-9.html をご覧ください。

于 2016-05-20T09:35:31.917 に答える
4

RStudioなどのGUIを使いたい方への注意事項。
並列処理を利用したい場合は、GUI を使用しないことをお勧めします。GUI を使用すると、コードと GUI プログラムの間のマルチスレッド プロセスが中断されるからです。registerDoMC以下は、 R のパッケージ ヘルプ マニュアルからの抜粋です。

Simon Urbanek によって最初に作成され、R 2.14.0 の並列パッケージに組み込まれたマルチコア機能は、現在のプロセスのコピーを生成するシステム fork 呼び出しを使用して、複数のコアまたはプロセッサを備えたマシンで R コードを並列実行するための関数を提供します。

マルチコア機能、したがって registerDoMC は、GUI 環境では使用しないでください。複数のプロセスが同じ GUI を共有するためです。

registerDoMC(cores = n)RStudioを使用してプログラムを実行するときに無効にすることで、OPで発生した同様のエラーを解決しました。マルチプロセッシングは、ベース R で最適に機能します。これが役立つことを願っています。

于 2016-11-30T08:39:34.427 に答える
1

私は今、同様の問題に直面しています。正解を知っているとは言いません。上記の両方の回答は、特にフォークが同時にメモリに追加の書き込み要求を作成している場合に、機能する可能性のある一連のアクションを提案しています。しかし、私は別の何かが難しさの原因かもしれないと考えていました.vis. メモリの断片化。の議論については、https://raspberrypi.stackexchange.com/questions/7856/log-says-i-cant-allocate-memory-but-i-have-more-than-half-of-my-memory-freeを参照してくださいUnix 系のユーザーに空きメモリが表示されるが、メモリの断片化によるメモリ不足エラーが発生する場合。これは、R が RAM の連続したブロックを好むため、特に R の犯人のようです。またあたり?Memory-limits要件は、RAM 自体ではなくアドレス空間に関するものであるべきです。したがって、これは正しくない可能性があります (特に 64 ビット マシンでは) YMMV.

于 2016-04-10T05:33:06.210 に答える