开发者

Why does this erlang code eat so much memory?

I'm going through Cesarini and Thompson's "Erlang Programming" (O'Reilly) and I made a solution to 4-2 but after playing around with it there are two problems:

  1. Every time I run go/3, "werl.ex开发者_开发知识库e" in windows chews up X amount of RAM. Every subsequent call takes up the same amount and it's never reclaimed.

  2. If I run go(Message,10000,10) it eats up 1.4GB RAM and crashes

I thought that in my second case, Erlang should handle this no problem from what I've been reading, so my guess is that I've somehow introduced a memory leak? I read the sections on memory leaks and tail recursion and don't see what I'm doing wrong.

Thanks in advance.

-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) ->
    [].


ProcList contains the list of Pids of all spawned processes. This list is received by all processes. For your example this means 10.000 x 10.000 Pids for each turn. That's quite a lot of memory!

Unless garbage collection can be set to get rid of the list as soon as the list is received, this won't work... try calling erlang:garbage_collect() before the waitMessage() tail calls.


I can't be entirely sure without seeing the "crash dump" but I suspect that the following might be causing some grief:

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

because your source listing shows that

-module(processRing). the module is named something different from what you are trying to get spawn to act on (module name is the first parameter).

In other words: you are trying to build a huge number of processes but every one of them will be failing and I suspect that the "garbage collection" will take some time to clean-up.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜