Erlang SSL TCP 服务器和垃圾收集

Erlang SSL TCP Server And Garbage Collection

编辑:问题似乎与 SSL acccpeting 和内存泄漏有关。

我注意到如果你有长期存在的进程(它是一个服务器),并且客户端将数据发送到服务器(recv),Erlang 垃圾收集永远不会被调用(或很少)

服务器需要数据(以执行操作),并且数据可以是可变长度的(由于像 "Hello" 或 "How are you doing" 这样的消息)。因此,Erlang 进程似乎会积累垃圾。

如何正确处理,Erlang进程要接触recv数据,这是不可避免的吗?或者您是否必须想出一种接触可变长度数据的次数更少的设计(比如立即将其传递给端口驱动程序)。

生成一个 worker 来处理数据是一个糟糕的解决方案(数百万个连接......),使用 worker 基本上是一回事,对吧?所以我的选择很少。

谢谢...

如果服务器保留接收到的消息的时间超过了它需要的时间,这是服务器实现中的错误。通常,当请求完成处理时,服务器应该忘记请求中所有或大部分对数据的引用,然后数据将变成垃圾并最终被收集。但是,如果您将来自每个请求的数据粘贴在进程状态的列表中,或者在 ets table 或类似的列表中,您将发生内存泄漏。

大于 64 字节的二进制文件有一点例外,因为它们是通过引用计数处理的,并且对于内存分配器来说,它看起来好像还不需要执行收集,尽管字节数此类二进制文件在堆外使用的数量可能非常大。

以防万一有人发现自己在同一条船上。这是 known/happening 一次用多个连接攻击服务器。我觉得。

在没有 ssl 的情况下,我的会话大约为 8KB,并且正在按预期为 GC 触发资源。使用 SSL,它增加到 ~150KB,并且内存不断增长。

http://erlang.org/pipermail/erlang-questions/2017-August/093037.html

您可能遇到了大型 SSL/TLS 会话表的问题。我们(OTP 团队)历来对这些表存在一些问题,因为如果您没有一些限制机制,它们可能会变得非常大。唉,在最新的 ssl 版本中,限制机制之一被打破了,但是这个补丁很容易修复它。作为解决方法,您还可以牺牲一些效率并禁用会话重用。

diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index ca9aaf4..ef7c3de 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -563,7 +563,7 @@ server_register_session(Port, Session, #state{session_cache_server_max = Max,

do_register_session(Key, Session, Max, Pid, Cache, CacheCb) ->
     try CacheCb:size(Cache) of
-   Max ->
+   Size when Size >= Max ->
    invalidate_session_cache(Pid, CacheCb, Cache);
_ ->    
    CacheCb:update(Cache, Key, Session),