spawn / 1和外部变量的共享

Bor*_*ner 3 heap erlang spawn

对于以下片段:

outer_func(State) ->
    spawn(fun()-> do_something(State) end).
Run Code Online (Sandbox Code Playgroud)

是否将State其共享或深复制到生成的进程堆?

Dog*_*ert 5

它将被深复制。这是一个简单的演示:

1> State = lists:seq(1, 1000000).
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
 23,24,25,26,27,28,29|...]
2> DoSomething = fun(State) -> io:format("~p~n", [process_info(self(), memory)]) end.
3> spawn(fun() -> DoSomething(State) end), spawn(fun() -> DoSomething(State) end), spawn(fun() -> DoSomething(State) end).
{memory,16583520}
{memory,16583520}
{memory,16583520}
Run Code Online (Sandbox Code Playgroud)

与此相反,以下是状态为大型二进制文件且与多个进程共享时永远不会“深度”复制的状态下的输出:

1> State = binary:copy(<<"a">>, 50000000).
<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"...>>
2> DoSomething = fun(State) -> io:format("~p~n", [process_info(self(), memory)]) end.
3> spawn(fun() -> DoSomething(State) end), spawn(fun() -> DoSomething(State) end), spawn(fun() -> DoSomething(State) end).
{memory,8744}
{memory,8744}
{memory,8744}
Run Code Online (Sandbox Code Playgroud)

因此,从1到1百万的整数列表的进程使用了​​大约16MB的内存,而具有大二进制文件的进程使用了​​8KB(二进制文件实际上应该是其中的可忽略的一部分)。