memory-leaks - GenServer 进程的内存泄漏

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

我最近遇到了一点麻烦:GenServer 进程使用的内存非常高,可能是因为大量的二进制泄漏。

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

我尝试在管理数据后使进程休眠,这部分起作用,因为进程使用的内存减少了很多,但由于二进制文件没有被GC,它们使用的内存量缓慢但稳定地增加,从大约 25 分钟内,不休眠时的 30 MB 到进程休眠时的 200MB。

我还尝试设置 :erlang.system_flag(:fullsweep_after, 0),这也有效并将进程使用的内存降低了大约 20%。

Beforeafter我必须说,进程时常使用的内存会减少到 60-70MB。

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

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

Here您可以在“进程”选项卡中从观察者处获取屏幕截图。正如你所看到的,GenServer 是像 cookies 怪物一样吃内存的人。

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

欢迎任何帮助。

代码位于 this Github Repository

Code of interest这可能是导致这个+ Applications tree4 个进程中有 3 个(<0.294.0>、<0.295.0>、<0.297.0> 正在使用 27MB of memory

预先感谢您的阅读。

最佳答案

您可以尝试将 :hibernate 原子添加到 GenStage 相关模块中的 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) 以获取有关违规行为的更多信息GenServers。

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

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

关于memory-leaks - GenServer 进程的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52297140/

相关文章:

ios - Instrument 释放后仍报内存泄漏

javascript - 如何销毁 THREEJS Scene?

java - Java Collection 的removeAll(Collection c) 方法是否强制对c 的元素进行垃圾回收?

firebase - 在 Elixir/Erlang 中验证 Firebase ID token

elixir - 列表的头尾分割不适用于大写字母

c++ - 可靠地确保 C++ 14 中的内存安全

ios - Swift 中 ALAssetRepresentation CGImage 的内存泄漏

docker - Docker容器内的GC统计信息

elixir - 无法转换为类型 :naive_datetime in query

在共享内存数组中使用 std::string 时的 c++ 内存泄漏