2017-11-15 4 views
2

Die CPU-Nutzung meiner Knoten-App nimmt allmählich zu. Ich habe festgestellt, dass Speicherlecks passieren. Durch AppDynamics habe ich festgestellt, dass es eine erhebliche Menge an beibehaltenem Speicher gibt, die im Laufe der Zeit unter processImmediate Aufrufbaum zunimmt. Als ich eindrang, fand ich das Problem mit settlePromises Funktion.Speicherleck - Versprechen in einer Schleife

App Dynamics screen shot

Ich möchte Ihre Meinung zu einer bestimmten Verwendung von Versprechen, die ich verwendet haben zu bekommen. Schleifen von Versprechen. Unten ist eine Beispielfunktionsstruktur solcher Verwendung.

var dataArray = []; //list of jsons 
var Promise = require('node-promise').Promise; 

function doSomething(){ 
    try{ 
     var promises = []; 
     //create function promises and push 
     for(var i in dataArray){ 
      var usage = {}; 
      usage["user"] = dataArray[i].user; 
      promises.push((function(ob){ 
       var log = extend({},ob); 
       return executeFunction(log)}).bind(null,usage)); 
     } 

     //loop and execute 
     var respArray = []; 
     return (promises.reduce(function(previous , current , index , array){ 
      try{ 
       return previous.then(function(resp){ 
        if(resp != null) 
         respArray.push(resp); 
        if(promises.indexOf(current)==promises.length -1){ 
         return current(); 
        } 
        else{ 
         return current(); 
        } 
       }); 
      }catch(ex){ 
       throw { ex : ex.stack}; 
      } 
     },delay())).then(function(){ 
      return data; 
     }); 
    } 
    catch(ex){ 
     console.log(ex,ex.stack); 
     throw { ex : ex.stack}; 
    } 
} 

function logTemplate(log){ 
    return models.Users.create(log).then(function(resp){ 
     return resp; 
    },function(err){ 
     return err; 
    }); 
} 

Das Heap Wachstum über eine Stunde wird in der Abbildung unten

enter image description here

Die obige Funktion eine synchrone Aktualisierung mit den Objekten in der Datenarray auszuführen hat, aufgetragen. Besteht die Gefahr eines Speicherlecks?

+1

Ja. Und die Chance ist, dass es in Ihrem Code ist, eher in der Bibliothek. Beginnen Sie mit dem Ausschneiden - isolieren Sie das Problem auf den kleinsten reproduzierbaren Code. – c69

+0

@ c69 Danke für den Kommentar. Sehen Sie offensichtliche Fehler bei der obigen Verwendung? Vielleicht werde ich versuchen, einen Testfall mit dieser Funktion zu haben, starte ihn mit setInterval und überprüfe das Heap-Wachstum. – chaithu

+1

Der Teil mit 'promests.push/promests.reduce' ist ein offensichtlicher Code-Geruch. Verschachtelte Versuch ... Catch ist Code-Geruch. For..in ist etwas, das seit 2009 niemand benutzt (Original Crockfords Buch). If..else Block innerhalb von reduzieren ist nutzlos - beide Zweige geben den gleichen Wert zurück. – c69

Antwort

-1

Nicht sicher, ob es die Ursache von Speicherlecks wäre, aber Ihre Funktion hat definitiv eine Tonne unnötigen Cruft, die mit Bluebirds Promise.mapSeries() und anderen Helfern von Bluebird aufgeräumt werden könnte.

Dies kann sehr gut dazu beitragen, Speicherlecks zu reduzieren.

doSomething Funktion zu 8 Zeilen reduziert:

function doSomething(){ 
    return Promise.delay(1000) // <-- specify time 
     .return(dataArray) 
     .mapSeries(function (el) { 
      return executeFunction({ user: el.user }); 
     }) 
     .filter(function (result) { 
      return result !== null; 
     }); 
} 
Verwandte Themen