Erlang SSL TCP服务器和垃圾收集

Erlang SSL TCP服务器和垃圾收集,erlang,otp,gen-tcp,Erlang,Otp,Gen Tcp,编辑:问题似乎与SSL访问和内存泄漏有关 我注意到,如果您有长期存在的进程(它是一个服务器),并且客户端将数据发送到服务器(recv),那么Erlang垃圾收集永远不会被调用(或者很少被调用) 服务器需要数据(执行操作),数据可以是可变长度的(由于“Hello”或“您好”之类的消息)。因此,Erlang进程似乎会积累垃圾 如何正确处理这个问题,Erlang进程必须接触recv数据,所以这是不可避免的吗?或者,您是否必须提出接触可变长度数据的次数更少的设计(如立即将数据传递给端口驱动程序) 产生一

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

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

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

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

产生一个worker来处理数据是一个糟糕的解决方案(数百万个连接…),使用worker基本上是一样的,对吗?所以我只有很少的选择


谢谢…

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


大于64字节的二进制文件有一点例外,因为它们是通过引用计数来处理的,对于内存分配器来说,似乎还没有必要执行收集,尽管这样的二进制文件在堆外使用的字节数可能相当大。

以防万一有人发现自己也在同一条船上。当同时使用多个连接敲打服务器时,就会发生这种情况。我想

在没有ssl的情况下,我的会话大约为8KB,并且如预期的那样为GC触发资源。随着SSL的增加,它的容量增加到了约150KB,并且内存不断增长


大型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),

您需要更多关于erlang GC的详细信息,我建议您可以尝试通过调用erlang:garbage_collect/0/1/2来尝试强制GC;看见如果GC:ing在每个请求都起作用之后,尝试将其减少到每个n:th请求,并为n计算出一个好的值。我不知道它是否解决了问题,但即使使用SSL进行所有这些修复,用户进程也会增加142+KB(这是没有任何逻辑的,只是一个SSL:recv)。这是不能接受的。我这边的解决方案是只使用SRP登录凭据,并为数据启用某种类型的加密(可能是AES)。