Memory management 列出垃圾收集
如果我这样做:Memory management 列出垃圾收集,memory-management,garbage-collection,erlang,Memory Management,Garbage Collection,Erlang,如果我这样做: List2 = [V || V <- List1, ...] List2=[V | | V如果您像这样创建新列表,新列表将包含第一个列表中的元素,一些元素将在两个列表之间共享。如果您扔掉第一个列表,共享元素仍然可以从新列表中访问,并且不会被视为垃圾 如何检查第一个列表是否是垃圾收集的?是否在erlang控制台中进行测试?控制台存储每个表达式的计算结果,这些表达式可能是您看不到垃圾收集列表的原因。在使用垃圾收集的任何语言中,您只需“丢失”对一段数据的所有引用,然后它就可以成
List2 = [V || V <- List1, ...]
List2=[V | | V如果您像这样创建新列表,新列表将包含第一个列表中的元素,一些元素将在两个列表之间共享。如果您扔掉第一个列表,共享元素仍然可以从新列表中访问,并且不会被视为垃圾
如何检查第一个列表是否是垃圾收集的?是否在erlang控制台中进行测试?控制台存储每个表达式的计算结果,这些表达式可能是您看不到垃圾收集列表的原因。在使用垃圾收集的任何语言中,您只需“丢失”对一段数据的所有引用,然后它就可以成为垃圾c已收集。只需从生成原始列表的函数返回,而不将其存储在任何其他“持久”位置(如进程字典),就可以回收内存。虚拟机应该管理垃圾收集。如果您使用gen_服务器,或者如果您使用“自制”服务器循环(状态),您应该始终使用相同的模式:
server_loop(State) ->
A = somefunc(State),
B = receive
mesg1 -> func1(...);
...
after Timeout ->
func2(...)
end,
NewState = func3(...),
server_loop(NewState).
只要一个进程处于活动状态,执行这个循环,VM就会分配和管理内存区域来存储所有需要的信息(变量、消息队列…+一些余量)据我所知,有一些空闲内存分配给进程,如果VM在释放内存后没有尝试快速恢复内存,但如果您使用erlang:garbage_collect(Pid)强制进行垃圾收集,您可以验证内存是否可用-请参见下面的示例
startloop() -> spawn(?MODULE,loop,[{lists:seq(1,1000),infinity}]).
loop(endloop) -> ok;
loop({S,T}) ->
NewState = receive
biglist -> {lists:seq(1,5000000),T};
{timeout,V} -> {S,V};
sizelist -> io:format("Size of the list = ~p~n",[length(S)]),
{S,T};
endloop -> endloop
after T ->
L = length(S) div 2,
{lists:seq(1,L),T}
end,
loop(NewState).
%% Here, NewState is a copy of State or a totally new data, depending on the
%% received message. In general, for performance consideration it can be
%% interesting to take care of the function used to avoid big copies,
%% and allow the compiler optimize the beam code
%% [H|Q] rather than Q ++ [H] to add a term to a list for example
以及VM中的结果:
2> P = lattice:startloop().
<0.57.0>
...
6> application:start(sasl).
....
ok
7> application:start(os_mon).
...
ok
...
11> P ! biglist.
biglist
...
2>P=lattice:startoop()。
...
6> 应用程序:启动(sasl)。
....
好啊
7> 应用程序:启动(操作系统)。
...
好啊
...
11> P!大名单。
大名单
...
%get_memory_data()->{总计、已分配、最差}。
14> memsup:get_memory_data().
{8109199360,5346488320,{<0.57.0>,80244336}}
...
23> P ! {timeout,1000}.
{timeout,1000}
24> memsup:get_memory_data().
{8109199360,5367361536,{<0.57.0>,80244336}}
14>memsup:get_memory_data()。
{8109199360,5346488320,{,80244336}}
...
23>P!{超时,1000}。
{超时,1000}
24>memsup:get_memory_data()。
{8109199360,5367361536,{,80244336}}
最坏的情况是循环进程:{,80244336}
...
28> P ! sizelist.
Size of the list = 0
sizelist
...
31> P ! {timeout,infinity}.
{timeout,infinity}
32> P ! biglist.
biglist
33> P ! sizelist.
Size of the list = 5000000
sizelist
...
36> P ! {timeout,1000}.
{timeout,1000}
37> memsup:get_memory_data().
{8109199360,5314289664,{<0.57.0>,10770968}}
38> P ! sizelist.
sizelist
Size of the list = 156250
39> memsup:get_memory_data().
{8109199360,5314289664,{<0.57.0>,10770968}}
...
46> P ! sizelist.
Size of the list = 0
sizelist
47> memsup:get_memory_data().
{8109199360,5281882112,{<0.57.0>,10770968}}
...
50> erlang:garbage_collect(P).
true
51> memsup:get_memory_data().
{8109199360,5298778112,{<0.51.0>,688728}}
。。。
28>P!sizelist。
列表的大小=0
尺码表
...
31>P!{超时,无限}。
{超时,无限}
32>P!大名单。
大名单
33>P!sizelist。
列表的大小=5000000
尺码表
...
36>P!{超时,1000}。
{超时,1000}
37>memsup:get_memory_data()。
{8109199360,5314289664,{,10770968}}
%%注意前一行中的垃圾收集:{,10770968}
...
28> P ! sizelist.
Size of the list = 0
sizelist
...
31> P ! {timeout,infinity}.
{timeout,infinity}
32> P ! biglist.
biglist
33> P ! sizelist.
Size of the list = 5000000
sizelist
...
36> P ! {timeout,1000}.
{timeout,1000}
37> memsup:get_memory_data().
{8109199360,5314289664,{<0.57.0>,10770968}}
38> P ! sizelist.
sizelist
Size of the list = 156250
39> memsup:get_memory_data().
{8109199360,5314289664,{<0.57.0>,10770968}}
...
46> P ! sizelist.
Size of the list = 0
sizelist
47> memsup:get_memory_data().
{8109199360,5281882112,{<0.57.0>,10770968}}
...
50> erlang:garbage_collect(P).
true
51> memsup:get_memory_data().
{8109199360,5298778112,{<0.51.0>,688728}}
38>P!sizelist。
尺码表
列表大小=156250
39>memsup:get_memory_data()。
{8109199360,5314289664,{,10770968}}
...
46>P!sizelist。
列表的大小=0
尺码表
47>memsup:get_memory_data()。
{8109199360,5281882112,{,10770968}}
...
50>erlang:垃圾收集(P)。
真的
51>memsup:get_memory_data()。
{8109199360,5298778112,{,688728}}
%%%GC后,进程不再是最坏的情况了为什么需要新列表?我有许多运行中的gen_服务器的列表处于状态,我希望定期清理过期项目以减少内存消耗。您确定没有在某个地方保留对列表1的引用,并且您实际上正在筛选是否有元素使List2比List1小?是的,我确定List2比List1小。如果我做List2=[binary\u to\u term(binary:copy(term\u to\u binary(V)))| | V不,我在实际应用程序上测试了垃圾收集器的行为,而不是在控制台上。我使用htop来监控内存消耗。有没有办法创建一个列表,而不在两个列表之间共享元素?我不明白你为什么需要这样做。你将有相同的元素使用相同的甚至更多的内存如果你有一个巨大的二进制文件,并且你匹配了其中的一些小部分,那么这种情况下,新的子二进制文件将只是指向带有偏移量和长度参数的主二进制文件的指针,因此你的二进制文件也不会被垃圾收集。为此,你有binary:copy/1
。如果L1=[A1,A2,A3,A4,A5]和L2=[A1]然后我希望A2-A5元素已经从内存中删除。你不需要复制元素,在这种情况下,它们必须被垃圾收集。再说一遍,列表中有什么类型的元素?有一些大二进制文件的部分吗?@P_A当没有对em.垃圾收集的整个要点不必明确地担心删除对象,也不必担心对象是否存在以及谁将删除它们。在Erlang中,就像大多数使用垃圾收集器的语言一样,没有显式的空闲的。拥有显式的空闲的总是充满危险的。在这种情况下如果系统真的比你更清楚的话。