如何防止NodeJS堆内存不足

时间:2017-05-12 23:32:17

标签: node.js ecmascript-6 stack-overflow heap-memory

我有以下错误:

  

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

这是以下代码的结果,当我尝试4个字符而不是8时,它可以正常工作:

const _secret = 'NICHOLAS';

const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

const maxLen = 8;

const maxGuesses = 999999999;

let answer;

let guess = '';

let curGuesses = 0;

function doCheck(passwordToReverseEngineer){
        function getRand(){
                return charset.split('')[Math.floor(Math.random() * charset.length)];
        };

        while (guess !== _secret){
                if (guess.length <= maxLen){
                        ++curGuesses;
                        guess += getRand();
                        console.log(`Now trying this combo: ${guess}`);
                }
                else if (curGuesses === maxGuesses) {
                        throw new Error(`Limit of ${maxGuesses} has been reached.`);
                }
                else {
                        guess = '';
                }

                setTimeout(()=>{
                        doCheck(passwordToReverseEngineer);
                });
        }

        answer = guess;

        console.log(`The secret has been cracked and it is ${guess} after ${curGuesses} attempts.`);

        return true;
}

我怎样才能避免这种情况,以便服务器在达到内存不足异常(例如上面的异常)之前可以处理n次猜测?

1 个答案:

答案 0 :(得分:0)

你应该遵循异步递归模型而不是使用while循环

function getRand() {/*code here*/}

function doCheck(password,attempts, key, callBack ){
  /* try to decrypt */
  const decrypted = decryptOperations(key);
  if(decrypted === secret){
    return callBack(null, decrypted);
  }

  if(attempts === MAX_ATTEMPTS) {
    return callBack(new Error('max num of trials'));
  }

  setTimeout(() => doCheck(passwords, attempts+1,...., callBack))

}

这是在回调模型之后,你可以实现类似的结果,返回一个内部创建的promise,并通过链而不是回调传递它。

`     功能doCheck(密码,尝试,密钥,解析,拒绝){       如果(!解析){          返回新的承诺((resolve,reject)=&gt; {            setTimeout(密码,尝试,密钥,解析,拒绝)          })       }

  const decrypted = decryptOperations(key);
  if(decrypted === secret){
    return resolve(decrypted);
  }

  if(attempts === MAX_ATTEMPTS) {
    return reject(new Error('max num of trials'));
  }

  setTimeout(() => doCheck(passwords, attempts+1,...., resolve, reject))

}

`

请不要理会解密逻辑实现,因为我不打算提供功能代码,而是向您展示如何完成异步逻辑。您也可以使用生成器,但我现在无法提供语法,因为我不熟悉它。我希望这有帮助