2017-08-24 35 views
0

我在Javascript性能问题,在工作最近导致飞机坠毁。随着现代化的目标我们的应用程序,我们正在进入运行我们的应用程序作为Web服务器,在其上我们的客户将通过一个浏览器(Chrome,火狐,...)连接,并有我们所有正在运行的HTML + JS网页接口。绩效的WebSockets BLOB解码造成内存问题

为了给你我们的性能要求的概述,我们从摄像机源的应用程序运行的图像处理,超过20个FPS在某些情况下运行,但在大多数情况下,各地2-3fps最大。

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

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

  1. 当没有更多内存可用时,C++ web服务器内存占用增加非常快并且崩溃。经过调查,发生这种情况时,网络使用充分,websocket缓存填满。我认为这是由于websocket采用TCP-IP的方式,因为套接字必须等待发送和接收消息才能发送下一个消息。
  2. 或者浏览器崩溃了一段时间后,显示喔唷,崩溃屏幕(见下图)。看起来在这种情况下,同样的事情或多或少发生,但似乎这次是由于垃圾收集策略。下图显示了应用程序运行时内存使用情况的打印屏幕,清楚地显示了锯齿图案。这似乎表明,垃圾收集正在进行的工作间隔越来越远。

Aw Snap screen

Saw memory pattern

我已经困问题降低到非常大的消息(> 100K上)以每秒快的速度发送。信息越大,发生得越快。为了使用我收到的消息,我启动了web worker,将我收到的blob传递给web worker,webworker使用FileReaderSync将消息转换为ArrayBuffer,并将其传递回主线程。我期望这篇文章有相当多的副本,但我对JS还不太熟悉,所以要确保这个说法。另外,我initialy做同样的事情,而不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数据arraybuffers另一种方法,将比我做什么更快?

我提前感谢您的帮助/意见。

回答

0

事实证明,内存问题是由于新WebWorker线,并在WebWorker新FileReaderSync线。

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

另外,事实证明,这个解码操作是不必要的,如果我想使用的WebSocket作为数组缓冲区。我只需要将websockets的binaryType属性设置为“arraybuffer”...

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