2

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

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

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

你怎么能正确处理这个,Erlang进程必须接触recv数据,所以它是不可避免的吗?或者您是否必须提出以较少次数接触可变长度数据的设计(例如立即将其传递给端口驱动程序)。

产生一个工人来处理数据是一个糟糕的解决方案(数百万个连接......),使用工人基本上是一回事,对吧?所以这让我几乎没有选择。

谢谢 ...

4

3 回答 3

3

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

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

于 2017-08-20T21:46:11.353 回答
0

以防万一有人发现自己在同一条船上。当一次用许多连接敲击服务器时,这是已知的/正在发生的。我认为。

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

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

于 2017-08-21T22:47:18.160 回答
0

大型 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),
于 2017-08-25T12:47:36.957 回答