2017-11-15 14 views
2

내 노드 앱의 CPU 사용률이 점차 증가하고 있습니다. 나는 메모리 누수가 발생하는 것을 발견했다. AppDynamics를 통해, 나는 시간이 지남에 따라 계속 증가하는 유지 된 메모리가 상당하다는 것을 발견했다. processImmediate 호출 트리. 내가 뚫고 들어갔을 때, 문제가 의 settlePromises 기능인 것으로 나타났습니다.메모리 누수 - 루프를 약속합니다.

App Dynamics screen shot

은 내가 사용하고 약속 하나 개의 특정 사용에 대한 귀하의 의견을 얻을 싶어요. 약속의 루핑. 아래는 그러한 사용법의 샘플 함수 구조입니다.

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; 
    }); 
} 

시간 동안 힙 성장은 아래 그림 상기 함수는 데이터 어레이 내의 객체 동기 업데이트를 수행하는

enter image description here

에 도시된다. 이걸로 메모리가 누출 될 가능성이 있습니까?

+1

예. 또한 기회는 라이브러리의 코드가 아닌 코드에 있습니다. 문제를 최소한의 재현 가능한 코드로 분리하십시오. – c69

+0

@ c69 코멘트 주셔서 감사합니다. 위의 사용법에서 명백한 실수가 있습니까? 어쩌면이 함수를 사용하여 하나의 테스트 케이스를 만들고 setInterval을 사용하여 실행하고 힙 증가를 확인하려고 할 것입니다. – chaithu

+1

'promises.push/promises.reduce'가있는 부분은 명백한 코드 냄새입니다. 중첩 된 try..catch는 코드 냄새입니다. For..in은 2009 년 이후 아무도 사용하지 않는 것입니다 (Crockford의 독창적 인 책). .. 만약 reduce의 내부 블록이 쓸모 없다면 - 두 가지 브랜치는 같은 값을 반환합니다. – c69

답변

-1

메모리 누수의 원인인지 여부는 확실치 않지만, 귀하의 기능에는 Bluebird의 Promise.mapSeries() 및 다른 Bluebird 도우미로 정리할 수있는 엄청난 양의 불필요한 젖꼭지가 있습니다.

이렇게하면 메모리 누수를 줄일 수 있습니다. 8 개 라인으로 감소

doSomething 기능 :

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