最近我遇到了一个小麻烦:GenServer进程使用的内存过高,可能是由于大量二进制泄漏造成的。
问题出在这里:我们通过GenServer接收大型二进制文件,然后将它们传递给使用者,然后使用者与该数据进行交互。现在,这些大型二进制文件永远不会分配给变量,并且GC也不会遍历它们。
我已尝试在管理数据后使进程休眠,这部分起作用是因为进程使用的内存减少了很多,但是由于二进制文件未进行GC处理,因此它们使用的内存量缓慢但稳定地增加。 30 MB而不进入休眠状态需要200 MB,然后在大约25分钟的时间内进入进程休眠状态。
我还尝试设置:erlang.system_flag(:fullsweep_after, 0)
,它也起作用并将进程使用的内存减少了大约20%。
Before和after。 我必须说它会不时地减少到进程使用的60-70MB。
编辑:使用:recon.bin_leak(15)释放:recon.bin_leak(15)的a lot of memory-result
无论如何,使用的内存仍然很高,我完全可以确定它可以解决。
Here,您在“进程”选项卡中的截图来自观察者。如您所见,GenServer就是像cookie怪兽那样吃掉内存的人。
我对此主题进行了很多研究,尝试了所有建议和可能的解决方案,尽管如此,我仍然处于这个位置。
欢迎任何帮助。
中Code of interest可能是导致此+ Applications tree的原因。其中有4个进程中的 3个(<0.294.0>,<0.295.0>,<0.297.0>正在使用27MB of memory 。
谢谢您的阅读。
答案 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章)