我为一些其他项目制作一个简单的IRC机器人已经玩了几天的PHP套接字了,机器人已启动并运行但是我注意到几个小时之后就会占用所有可用内存。
我一直在使用memory_get_usage()进行一些调试,并且在确保我将我在循环中使用的所有变量都归零后,导致内存使用量增加的唯一因素是“fgets()”,我似乎无法弄清楚为什么它在使用后不会释放它的记忆。
我一直在做错的任何想法?
Psudo代码:
$this->socket = stream_socket_client(server, port);
stream_set_blocking($this->socket, 0);
stream_set_timeout($this->socket, 600);
while(true) {
usleep(500000);
$data = fgets($this->socket, 8192);
*work with data if strlen > 0*
$data = null;
}
请注意,我已禁用阻止,因此即使在正在观看的频道上没有任何活动,机器人也可以执行一些后台任务。
调用fgets之前和之后的内存使用情况(与stream_get_line相同的结果):
int(959504)
string(0) "" //Data returned from gets
int(967736)
请注意,我正在测试SSL服务器,这可能是某种SSL“溢出”吗?
或者,如果您想亲自查看整个代码:https://github.com/Ueland/VikingBot
答案 0 :(得分:1)
根据https://bugs.php.net/bug.php?id=38962,它是在特定的php 5.2.6版本中重现的错误。因此,如果您使用更高版本,您可以报告您的发现:)
答案 1 :(得分:0)
简单地将变量设置为null不会释放先前数据正在使用的内存。它只是将数据与变量断开连接。在将来的某个时刻,PHP垃圾收集器可以启动并实际释放内存,但不能保证这样做。垃圾收集是一项非常昂贵的操作,CPU使用方面,除非绝对必须,否则PHP不会运行GC。通常情况下,当内存使用率接近memory_limit
设置时。
您可以尝试通过gc_collect_cycles()
答案 2 :(得分:0)
使用stream_get_line()而不是fgets()
答案 3 :(得分:0)
终于搞清楚了。我意识到,我没有使用“while(true)”,而是使用了一个只在完成时调用自身的函数,因此保留了自身的引用。 Dunno为什么我之前没有注意到它,但至少现在内存使用量保持不变。 ;)
感谢所有建议!