【问题标题】:PHP memory leak in client socket (UDP)客户端套接字 (UDP) 中的 PHP 内存泄漏
【发布时间】:2015-08-24 11:48:23
【问题描述】:

:)

我正在尝试从我的 php 服务器中的 c# 实时应用程序接收数据,然后根据数据在浏览器中移动图片。

数据收发没有问题,但是运行代码时chrome的内存占用越来越大。

如果我在 while 循环中关闭套接字,性能会变得非常低,但内存使用会正常。所以这是关于打开的套接字...

这里是php代码:

<?php 
//http://www.binarytides.com/udp-socket-programming-in-php/
//Create a UDP socket
if(!($sock = socket_create(AF_INET, SOCK_DGRAM, 0)))
{
   die("Couldn't create socket: [$errorcode] $errormsg \n");
}
echo "Socket created \n";
// Bind the source address
if( !socket_bind($sock, "0.0.0.0" , 41181) )
{
    die("Could not bind socket : [$errorcode] $errormsg \n");
}
echo "Socket bind OK \n";

//Do some communication, this loop can handle multiple clients
while(1)
{
//echo "Waiting for data ... \n";
   $r = socket_recvfrom($sock, $buf, 20, 0, $remote_ip, $remote_port);
 ?>

 <script type="text/javascript">    
    var data =  "<?php echo $buf ?>";     
 </script>

<?php
 }
 socket_close($sock);
 ?>

这里是c#函数(数据发送者):

 public static void SendUDP(string hostNameOrAddress, int destinationPort, string data, int count)
    {
    //class member :  Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram, ProtocolType.Udp);
    //socket is defined as class member and used here
        for (int i = 0; i < count; i++)
        {
            socket.SendTo(buffer, endPoint);
        }
    }    

谢谢! :)

【问题讨论】:

  • 你的问题到底是什么?
  • 我希望内存使用稳定,而不是一直增加。
  • 你是在浏览器中运行这个,还是为什么要将结果包装在一个 JS 标签中?
  • 是的!我在第二行提到了“在浏览器中”。
  • 我想从c# app发送数据到php服务器,然后php服务器再发送数据到浏览器。

标签: php sockets memory-leaks udp


【解决方案1】:

您使用的技术称为“长轮询”。这是一种模拟双向通信的有趣方式,尤其是在旧浏览器中,但也有其缺点。

问题在于,随着时间的推移,您正在向浏览器发送大量有效负载。

当您不断地向浏览器写入内容时,页面大小会增加,DOM 树也会随之增加。所有这些都必须存储在内存中。我假设当您只发送几个脚本块时,性能仍然可以。但是成千上万的人当然会吃掉你的记忆。

此外,如果您使用诊断工具,例如 Chrome 开发者工具或 Firefox 中的 Firebug,它们会存储大量调试信息,这也会消耗大量内存。 (尝试禁用它们。)

如果您只是为了好玩和试验而编写此代码,则不必担心内存消耗;这是长轮询固有的。

但是,如果您尝试编写具有真正双向通信的 Web 应用程序,则应该使用 Web Sockets 之类的东西(并且可能在服务器端使用与 PHP 不同的语言)。

【讨论】:

  • 这不是为了好玩,我正在尝试使用浏览器作为界面编写桌面应用程序。我用 Node.js 进行了这个测试,没问题。我是不是写错了 php 脚本?
  • * - 页面大小不使用内存,因为在这种情况下,这也不适用于 Node.js。 ** 检查内存时不使用开发工具。
  • 问题是打开的socket并没有释放它使用的内存,因为如果我每次收到消息都关闭socket,内存是ok的。
  • PHP 代码看起来没问题。您可以使用memory_get_usage(true) 转储循环内的内存使用情况。顺便说一句,如果您的内存泄漏在 Chrome 中,PHP 就不是问题。
  • php 中有一些 stream_socket_server() 。我不应该使用它吗?
【解决方案2】:

这不是我问题的真正答案,但我的经验可能会对某人有所帮助。

我不能用 PHP 服务器做这个“长轮询”,这是 PHP 的错,而不是浏览器。 我使用 Node.js 服务器开发了一个很好的应用程序。

我的 C# 应用程序用于处理来自相机的图像。产生图像处理的实时数据被发送到 Node.js 服务器并从服务器发送到浏览器。

现在我使用 Web 技术开发了一个在 .Net 中很难实现的图形用户界面,它还有许多其他好处...

【讨论】:

    猜你喜欢
    • 2015-08-26
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多