我正在通过Cesarini和Thompson的“Erlang编程”(O'Reilly),我为4-2做了一个解决方案但是在玩完之后有两个问题:
每次运行go / 3时,Windows中的“werl.exe”都会占用X量的RAM。每次后续通话都会占用相同的金额而且永远不会被回收。
如果我运行go(消息,10000,10)它会占用1.4GB内存并崩溃
我认为在我的第二种情况下,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) -> [].
答案 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
的行为不同(模块名称是第一个参数)。
换句话说:你正在尝试构建大量的进程,但是每个进程都会失败,我怀疑“垃圾收集”需要一些时间来清理。