GenServer进程的内存泄漏

时间:2018-09-12 14:06:49

标签: memory-leaks garbage-collection elixir gen-server

最近我遇到了一个小麻烦:GenServer进程使用的内存过高,可能是由于大量二进制泄漏造成的。

问题出在这里:我们通过GenServer接收大型二进制文件,然后将它们传递给使用者,然后使用者与该数据进行交互。现在,这些大型二进制文件永远不会分配给变量,并且GC也不会遍历它们。

我已尝试在管理数据后使进程休眠,这部分起作用是因为进程使用的内存减少了很多,但是由于二进制文件未进行GC处理,因此它们使用的内存量缓慢但稳定地增加。 30 MB而不进入休眠状态需要200 MB,然后在大约25分钟的时间内进入进程休眠状态。

我还尝试设置:erlang.system_flag(:fullsweep_after, 0),它也起作用并将进程使用的内存减少了大约20%。

Beforeafter我必须说它会不时地减少到进程使用的60-70MB。

编辑:使用:recon.bin_leak(15)释放:recon.bin_leak(15)的a lot of memory-result

无论如何,使用的内存仍然很高,我完全可以确定它可以解决。

Here,您在“进程”选项卡中的截图来自观察者。如您所见,GenServer就是像cookie怪兽那样吃掉内存的人。

我对此主题进行了很多研究,尝试了所有建议和可能的解决方案,尽管如此,我仍然处于这个位置。

欢迎任何帮助。

代码在this Github Repository

Code of interest可能是导致此+ Applications tree的原因。其中有4个进程中的 3个(<0.294.0>,<0.295.0>,<0.297.0>正在使用27MB of memory

谢谢您的阅读。

1 个答案:

答案 0 :(得分:0)

您可以尝试在与GenStage相关的模块中将:hibernate原子添加到handle_events返回值中。例如:

def handle_events(events, _from, %{handler: handler, public: public} = state) do
  public = handle(handler, events, public)
  {:noreply, [], %{state | public: public}, :hibernate}
end

另一种选择是在:recon.bin_leak()之后记录PID,然后将它们传递给Process.info(PID),以获得有关有问题的GenServer的更多信息。

一些其他资源: https://elixirforum.com/t/extremely-high-memory-usage-in-genservers/4035/23

https://www.erlang-in-anger.com/(特别是关于内存泄漏的第7章)