为什么这个erlang代码会占用如此多的内存?

时间:2009-12-23 22:30:24

标签: memory-leaks erlang

我正在通过Cesarini和Thompson的“Erlang编程”(O'Reilly),我为4-2做了一个解决方案但是在玩完之后有两个问题:

  1. 每次运行go / 3时,Windows中的“werl.exe”都会占用X量的RAM。每次后续通话都会占用相同的金额而且永远不会被回收。

  2. 如果我运行go(消息,10000,10)它会占用1.4GB内存并崩溃

  3. 我认为在我的第二种情况下,Erlang应该从我读过的内容中解决这个问题,所以我的猜测是我以某种方式引入了内存泄漏?我阅读了有关内存泄漏和尾递归的部分,并没有看到我做错了什么。

    提前致谢。

    -module(processRing).
    -export([waitMessage/0,go/3]).
    
    % Spawn M processes and pass Message around to each process N times
    go(Message,M,N) ->
    
        ProcList = buildList(M),
        [H | T ] = ProcList,
        register(firstProc,H),
        H ! {self(), T, ProcList, Message, N}.
    
    waitMessage() ->
        receive 
            {_, _, _, _, 0} ->
                io:format("end!", []);
    
            {From, [H|T], AllProcs, Message, N} ->
                %io:format("~w:~w from:~w~n n=~w",[self(),Message,From,N]),
                H ! {self(), T, AllProcs, Message, N},
                waitMessage();
    
            {From, [], AllProcs, Message, N} ->
                io:format("~w:~w (Last in list) from:~w n=~w~n",[self(),Message,From,N]),
                firstProc ! {self(), AllProcs, AllProcs, Message, N - 1},
                waitMessage();
    
            Other ->
                io:format("other:~w~n",[Other])
        end.
    
    buildList(N) when N > 0 ->
        [spawn(processRing,waitMessage,[]) | buildList(N - 1)];
    
    buildList(0) ->
        [].

2 个答案:

答案 0 :(得分:2)

ProcList包含所有衍生进程的Pids列表。所有进程都会收到此列表。对于您的示例,这意味着每回合10.000 x 10.000 Pids。这是相当多的记忆!

除非可以设置垃圾收集以在收到列表后立即删除列表,但这不起作用...尝试在erlang:garbage_collect()尾调用之前调用waitMessage()

答案 1 :(得分:0)

如果没有看到“崩溃转储”,我无法完全确定,但我怀疑以下情况可能会引起一些悲伤:

[spawn(chap9q1,waitMessage,[]) | buildList(N - 1)];

因为您的源列表显示

-module(processRing).该模块的名称与您尝试spawn的行为不同(模块名称是第一个参数)。

换句话说:你正在尝试构建大量的进程,但是每个进程都会失败,我怀疑“垃圾收集”需要一些时间来清理。