我有一个具有以下模式的应用程序:
问题是“系统”部分不断增长(约1GB /周)。
我的问题是如何调试存储在那里的内容或谁在该区域分配内存而不是释放它。
我已经测试了列表:keysearch / 3 并且它似乎没有泄漏内存,因为这是我正在使用的唯一本机内容(没有端口,没有驱动程序,没有NIF ,没有BIF,没有)。 Erlang版本是R15B03。
以下是当前 erlang:memory()输出(轻微流量,应用程序于2月3日开始):
[{total,378865650},
{processes,100727351},
{processes_used,100489511},
{system,278138299},
{atom,1123505},
{atom_used,1106100},
{binary,4493504},
{code,7960564},
{ets,489944},
{maximum,402598426}]
这是一个64位系统。正如您所看到的,“系统”部分大约有270MB,“进程”大约为100MB(夜间降至约16MB)。
答案 0 :(得分:4)
似乎我发现了这个问题。
我有一个“process_killer”gen_server,其中进程可以订阅定期GC或kill。它的订阅函数在某些进程收到的每条消息上被调用,以推迟GC / kill(类似于重新武装)。
此进程执行erlang:monitor如果尚未监视以捕获死进程并将其从监视列表中删除。如果我在每个处理过的消息上评论我们的重新订阅行,“系统”区域似乎表现正常。这意味着我的process_killer中的一个错误是泄漏监视器引用(记住你可以多次调用erlang:monitor,每次调用都会创建一个引用)。
我引导了这个想法,因为我测试了一个简单的模块,它调用了erlang:监视器循环,我看到每个调用增加了~13个字节的“系统”区域。
工人们自己也没关系,因为他们会随着他们的监视器一起死去。有一个长时间运行(从应用程序启动,随应用程序停止)进程将所有消息发送给在每个收到的消息上调用GC重新启动的工作人员,因此我们讨论的是每个生成的数万个监视器小时,从未放行。
我在这里写这个答案以供将来参考。
TL; DR;确保在长时间运行的过程中没有泄漏显示器参考。