2017-08-24 3 views
0

Javascriptでパフォーマンスの問題が発生し、最近クラッシュが発生しています。私たちのアプリケーションを近代化する目的で、クライアントがブラウザ(chrome、firefox、...)を介して接続し、すべてのインタフェースをHTML + JSのWebページとして実行するWebサーバーとしてアプリケーションを実行することを検討しています。Websocketsのパフォーマンスでブロブのデコードでメモリの問題が発生する

私たちのパフォーマンスニーズの概要を説明するために、アプリケーションはカメラソースから画像処理を実行しますが、場合によっては20fps以上で実行されますが、ほとんどの場合2-3fps程度です。

基本的に、私たちにはHTTPリクエストであるC++で書かれたWebサーバーがあり、ユーザーはインターフェイスのHTMLページとアプリケーションの対応するJSスクリプトを提供します。 2つのアプリケーション間の通信を簡単にするために、WebページとC++サーバーの間にWebソケットを開いて、書式設定されたメッセージを前後に送信します。これらのメッセージはいくつかのモスまでかなり大きくなることがあります。

FPSが比較的低い間は、すべて正常に動作します。 fpsが増加すると、次の2つのことが起こります。

  1. C++ Webサーバーのメモリフットプリントがかなり高速になり、使用可能なメモリがなくなるとクラッシュします。調査の後、これはネットワーク使用量がいっぱいになり、websocketキャッシュがいっぱいになると起こります。これは、ソケットが次のメッセージを送信するためにメッセージを送受信するのを待たなければならないので、これがwebsocket TCP-IPのやり方によるものだと思います。
  2. しばらくするとブラウザがクラッシュし、Awスナップ画面が表示されます(下図参照)。その場合、同じことが多かれ少なかれ起こっているようですが、ガベージコレクション戦略のためにこの時間がかかるようです。下の他の図は、アプリケーションが実行されているときのメモリ使用量の印刷画面を示しています。ガベージコレクションは、さらに遠く離れた間隔で作業していることを示しているようです。

Aw Snap screen

Saw memory pattern

私は毎秒速い速度で送信されている非常に大きなメッセージ(> 100Ko)まで問題が閉じ込められています。メッセージが大きければ大きいほど、それは速く起こります。受信したメッセージを使用するには、Webワーカーを開始し、受け取ったブロブをWebワーカーに渡します.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. ブロブデータを配列バッファとして読み込む方法はありますか?

ご協力いただきありがとうございます。

答えて

0

メモリの問題は、新しいWebWorker行とWebWorkerの新しいFileReaderSync行によるものです。

これらを削除すると、パフォーマンスが大幅に向上しました。

また、配列バッファとしてwebsocketを使用する場合、このデコード操作は不要です。私はちょうど "arraybuffer"にwebsocketsのbinaryType属性を設定する必要があります...

したがって、***問題の非常に単純な解決策:-)

関連する問題