11

我有一個應用程序通過WebSocket頻繁接收二進制消息(至少每幀一次)並繪製數據,使用canvas/webgl。我注意到我有一個非常好的鋸齒形內存配置文件;大量短暫的數據塊。 enter image description hereWebSocket頻繁onmessage zero-copy

這並不讓我感到意外,因爲我從onmessage收到一個對象,至少每16ms一次,用於繪製然後解除引用。

我的問題是:有避免/最小化的提示嗎?根據WebSocket API,在每個套接字接收呼叫上分配新內存似乎沒有替代方案。在另一種語言/環境中,我會預先分配一些內存並接收到緩衝區中,以避免爲短期對象不斷分配內存,但我想不出在瀏覽器中使用JavaScript實現這一點的明顯方法。

僅供參考,這裏是我的框架視圖。

enter image description here

我不知道這是否空閒時間是垃圾收集?任何開發工具忍者的見解將不勝感激。如果

+0

你有任何的代碼示例分配內存的更多信息?開始了什麼?一把小提琴? – Anonymous0day

+1

我在WebSockets上從我的樹莓派流式傳感器日期有同樣的問題。恐怕有,並且將無法干擾JavaScript中的WebSockets的內存分配。我的研究沒有帶來任何結果。 – windm

+0

你希望實現什麼?程序運行多長時間,一致的長期性能有多重要?看到一些代碼或代碼示例會很棒 –

回答

1

不知道我理解你的問題,但你可以在任何其他語言聲明全局陣列狀,並用它作爲循環緩衝器,例如:

var buffer = []; 
var bufferLength = 1000; 
var start = 0; 
var end = 0; 
var content = 0; 

socket.onmessage(function(msg) { //msg allocated 
    end %= bufferLength; 
    if (end == start && content != 0) 
     console.log("Buffer is full"); 
    else { 
     content++; 
     buffer[end++] = msg; //reference to msg saved so it's not destroyed at the end of the callback 
    } 
}); 

function getNext() { 
    start %= bufferLength; 
    if (start == end && content == 0) 
     console.log("Buffer is empty"); 
    else { 
     content--; 
     return buffer[start++]; // returns reference to next msg 
    } 
} 

編輯:我修改的答案更明確了存儲週期:

JS將分配上的WebSockets接收到的信息存儲和將創建一個參考,以它叫msg,將給予您在用於onmessage定義回調設置了一個param。

注意JS GC只會在代碼中不再引用它時才銷燬該內存塊。

上面我做的是將該引用保存在緩衝區中,以便在回調完成後該值不會被破壞,您可以稍後使用getNext訪問它。你不需要分配新的內存,因爲JS爲你做了。

如果您想克隆或創建msg的不同副本,則有一些不同的選項。一個簡單的選擇,讓你克隆非圓形的JSON對象是:

var newJSON = JSON.parse(JSON.stringify(msg)); 

您可以找到有關JS在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management

+0

這並不能回答我的問題,具體是關於「在每個套接字上分配的新內存接收呼叫」。 – sethro

+0

我特別關心分配給傳遞給'onmessage'對象的內存:'msg'。我認爲你誤解了我的問題。我正在尋求一種方法來預先分配一個緩衝區,WebSocket或者其他一些API將用來從底層套接字接收的緩衝區。 – sethro

+1

好的,我現在明白你的問題了。我不認爲你可以使用JS做任何事情。您可能能夠減輕Chrome chrome中的零拷貝光柵化程序的一些總延遲:// flags /#enable-zero-copy,以便在webgl中呈現更快的速度。另外,考慮到你的問題是關於內存訪問的問題,你可以使用從服務器發送的數據包的數量/大小,更少/更大的數據包將減少操作的數量。 –