如何防止 NodeJS 堆内存不足

How to prevent NodeJS heap out of 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 次猜测?

您应该遵循异步递归模型而不是使用 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))

}

这是遵循回调模型,您可以获得类似的结果return使用内部创建的承诺并通过链而不是回调传递它。

` 函数 doCheck(密码、尝试、密钥、解析、拒绝){ 如果(!解决){ return 新的承诺((解决,拒绝)=> { 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))

}

`

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