Websockets blob解码中的性能导致内存问题

时间:2017-08-24 16:14:09

标签: javascript memory websocket crash garbage-collection

我在Javascript中遇到了性能问题,导致最近崩溃。为了使我们的应用程序现代化,我们正在考虑将我们的应用程序作为Web服务器运行,我们的客户端将通过浏览器(chrome,firefox,...)连接,并将所有接口作为HTML + JS网页运行。

为了向您概述我们的性能需求,我们的应用程序从相机源运行图像处理,在某些情况下以超过20 fps的速度运行,但大多数情况下最大约为2-3fps

基本上,我们有一个用C ++编写的Web服务器,HTTP请求,并为用户提供接口的HTML页面和应用程序的相应JS脚本。 为了简化两个应用程序之间的通信,我然后在网页和c ++服务器之间打开一个Web套接字来来回发送格式化的消息。这些消息可能非常大,可达几个Mos。

只要FPS保持相对较低,这一切都很有效。当fps增加时,会发生以下两件事。

  1. 当没有更多内存可用时,c ++ webserver内存占用量增加得非常快并崩溃。经过调查,当网络使用率已满并且websocket缓存填满时会发生这种情况。我认为这是由于websocket TCP-IP的做法,因为套接字必须等待发送和接收消息才能发送下一个消息。
  2. 或者浏览器在一段时间后崩溃,显示Aw snap屏幕(见下图)。在这种情况下似乎或多或少发生了同样的事情,但这次似乎是由于垃圾收集策略。下图显示了应用程序运行时内存使用情况的打印屏幕,清晰显示了锯齿图案。它似乎表明垃圾收集正在以越来越远的间隔进行工作。
  3. Aw Snap screen

    Saw memory pattern

    我把问题困在每秒快速发送的非常大的消息(> 100Ko)。信息越大,发生得越快。为了使用我收到的消息,我启动一个Web worker,将收到的blob传递给Web worker,webworker使用FileReaderSync将消息转换为ArrayBuffer,并将其传递回主线程。我希望这个副本有很多副本,但我不是很精通JS,所以要确定这个陈述。另外,我最初在没有webworker(FileReader)的情况下做了同样的事情,但帧率和CPU使用率非常糟糕......

    以下是我调用解码消息的代码:

    function OnDataMessage(msg)
    {
        var webworkerDataMessage = new Worker('/js/EDXLib/MessageDecoderEvent.js'); // please no comments about this, it's actually a bit nicer on the CPU than reusing the same worker :-)
        webworkerDataMessage.onmessage = MessageFileReaderOnLoadComManagerCBack;
        webworkerDataMessage.onerror=ErrorHandler;
        webworkerDataMessage.postMessage(msg.data);
    }
    
    function MessageFileReaderOnLoadComManagerCBack(e)
    {
        comManager.OnDataMessageReceived(e.data);
    }
    

    和webworker代码:

    function DecodeMessage(msg)
    {
        var retMsg = new FileReaderSync().readAsArrayBuffer(msg);
        postMessage(retMsg);
    }
    
    function receiveDecodingRequest(e)
    {
        DecodeMessage(e.data);
    }
    
    addEventListener("message", receiveDecodingRequest, true);
    

    我的问题如下:

    1. 有没有办法让GC不必收集这么多内存,例如告诉我使用的一些部分来重用缓冲区而不是重新创建它们,或者保持GC工作间隔固定?这是我知道如何用C ++做的,但是在JS?

    2. 我应该为我的大型有效载荷使用另一种方法吗?请记住,传输应该尽可能快。

    3. 是否有另一种方法可以将blob数据作为数组缓冲区读取,这比我做得更快?

    4. 我提前感谢你的帮助/评论。

1 个答案:

答案 0 :(得分:0)

事实证明,内存问题是由于新的WebWorker行和WebWorker中的新FileReaderSync行所致。

删除这些大大提高了性能!

另外,如果我想将websocket用作数组缓冲区,则无需进行此解码操作。我只需要将websockets的binaryType属性设置为" arraybuffer" ...

总而言之,这是解决***问题痛苦的一个非常简单的解决方案: - )