2016-01-20 130 views
0

我有一個腳本,允許我在畫布上顯示攝像頭,並在某些間隔內「下載」特定的幀。 當時間參數很大時(每2秒捕獲30分鐘),我遇到了麻煩。它工作順利約15分鐘,然後崩潰(Firefox關閉,內存不足錯誤)。此外,重新啓動Firefox後,有時會在3-4分鐘內拍攝很多0字節的照片,然後再次開始工作。我在放置在實驗室中的舊的2 GB RAM機器上運行該程序,是否有減少內存使用量的方法?從畫布中間隔拍攝照片

這是一段帶參數和功能realizarCapturas的代碼。 我可以添加靜止代碼,但我認爲要優化的部分應該是這一個。

var frecuenciaComienzoCaptura = 1; // how long till next capture 
    var frecuenciaCaptura = 3; //seconds between photos 
    var duracion = 5; // amount of photos to capture 

    function realizarCapturas(){ 
    var i = 1; 
    var interval = setInterval(function(){ 
     if(i <= duracion){ 
     context.drawImage(video, 0, 0, 640, 480); 

     var imagen = document.getElementById("imagen"); 
     imagen.href = canvas.toDataURL("image/png"); 

     var now = new Date(); 
     var filename = formatNumber(now.getHours()) + "-" + formatNumber(now.getMinutes()) + "-" + formatNumber(now.getSeconds()); 

     imagen.download = filename + ".png"; // Make sure the browser downloads the image 
     imagen.click(); // Trigger the click 
     i = i+1; 
     }else{ 
     clearInterval(interval); 
     } 
    }, frecuenciaCaptura * 1000); 
    } 



    setInterval(function(){ 
    realizarCapturas(); 
    }, frecuenciaComienzoCaptura * 1000 * 60 * 60); 

    realizarCapturas(); 


}, false); 
+0

您可能會疊加未完成的操作。嘗試使用單個'requestAnimationFrame'循環而不是多個間隔進行重構。使用開發工具監視資源使用情況。 – markE

回答

1

作爲一個規則不要使用setInterval,因爲它可以調用堆棧溢出,這是非常困難的代碼來檢測源。

你的問題是,你沒有清除你正在產生的所有間隔,因此你每創建一個新的間隔事件3秒鐘。最終,運行一小段代碼所需的時間將比您創建的所有時間間隔事件所能處理的時間長,因此每個時間間隔將繼續將其事件推送到調用堆棧中,但不會有機會成爲直到有更多的時間間隔放在堆棧上,最終導致崩潰。 setInterval也不保證事件之間的時間是準確的。

改爲使用setTimeout。這樣,您只會根據需要生成事件,而且您無需保留關閉事件的句柄。

下面是您編寫的代碼,以便您永遠不會有調用堆棧溢出。

var frecuenciaComienzoCaptura = 1 * 1000* 60 * 60; // how long till next capture 
var frecuenciaCaptura = 3 * 1000; //seconds between photos 
var duracion = 5; // amount of photos to capture 
var counter = 0; 
// the capture function 
var captura = function() {  
    counter = counter + 1; 
    if(counter < duracion){ // do we need more images? 
     // only create timer events as needed. 
     setTimeout(captura, frecuenciaCaptura); //set time till next image 
    } 
    context.drawImage(video, 0, 0, 640, 480); 
    var imagen = document.getElementById("imagen"); 
    imagen.href = canvas.toDataURL("image/png"); 

    var now = new Date(); 
    var filename = formatNumber(now.getHours()) + "-" + formatNumber(now.getMinutes()) + "-" + formatNumber(now.getSeconds()); 

    imagen.download = filename + ".png"; // Make sure the browser downloads the image 
    imagen.click(); // Trigger the click 
} 

function realizarCapturas() { 
    // request next batch of captures by only creating one timer event as we need 
    setTimeout(realizarCapturas,frecuenciaComienzoCaptura); 
    counter = 0; // reset counter 
    captura(); // capture timages 
} 

// start captures. 
realizarCapturas(); 
+0

似乎在今天下午工作完美,它也似乎更容易記憶的要求,因爲圖像創建幾乎在同一時間的實際時間 –