win*_*old 8 sockets memory-leaks raku
在 raku (v2022.07) 应用程序中处理日志流(通过 UDP)时,我使用 IO::Socket::Async 遇到了内存泄漏问题。
我将代码提取到一个更简单的程序中,如下所示(〜与https://docs.raku.org/type/IO::Socket::Async中的代码相同):
#!/usr/bin/env raku
#
my $socket = IO::Socket::Async.bind-udp('localhost', 24225);
react {
whenever $socket.Supply -> $v {
print $v if $v.chars > 0;
};
};
Run Code Online (Sandbox Code Playgroud)
它泄漏了大量的内存 - 我让它运行大约 12 小时,当我检查时 - 仍在运行(在 1T 内存机器上) - 使用 ps auwwx [pid]
它显示 VSZ 和 RSS 为 314974456 和 20739784(因此,v 大小大约为 300G,驻留数量为 20G)。
[顺便说一句,UDP 流量相当轻 - 平均每秒 350 个(约 100 字节)数据包(峰值达到约 1000 个/秒)]
所以..我在perl5中重写了上面的内容(在类似的泄漏结果和几个raku变体之后),它很快稳定在大约8M驻留-这很好/稳定/等等。- 但我更喜欢这个进程来提供 raku 通道(没有单独的 perl 进程/文件尾部等)。
我的环境:FreeBSD 13.1-RELEASE-p2 GENERIC amd64 和 raku:v2022.07 构建于 MoarVM 2022.07(与 rakubrew 一起安装)。
我猜这是 freebsd 上 raku 所独有的,但不确定。
我确实尝试将 (rakubrew) 升级到 v2022.12,看看问题是否已解决 - 但在重建模块 (zef) 中,太多失败了(Digest/Digest::HMAC 的一些问题) - 所以我不得不恢复到 2022.07。
我一定会感谢任何解决泄漏问题的建议或解决从 UDP 端口读取问题的替代方法。
不完全是您问题的解决方案,但您可以使用内置功能从 Raku 代码中监控内存使用情况:
use Telemetry;
say T{"max-rss"};
Run Code Online (Sandbox Code Playgroud)
另请记住,Supply 默认解码 unicode 字符。如果您的协议是二进制的,您可以添加:bin
到套接字参数以避免将二进制数据视为文本。