discord.js项目设置max-old-space-size后仍报JavaScript堆内存溢出错误
故障原因分析
- 核心致命问题:死循环导致无限创建定时器
你的代码中while (i < 10)循环体内没有对i做自增操作,i的值永远为1,循环永远不会终止,会持续无限调用task()函数,每秒创建成千上万个setTimeout定时器。每个定时器绑定的异步请求、Embed实例、Discord API调用相关对象都会常驻内存,无论你调多大的堆内存上限,最终都会被耗尽触发OOM。 - 事件绑定逻辑错误
你将定时查询逻辑绑定在了message事件上,意味着每收到一条频道消息,就会新增一批定时任务,就算修复了死循环,随着频道消息量增长,定时任务会重复叠加,同样会导致内存持续上涨泄漏。而且discord.js v13及以上版本早已废弃message事件,改用messageCreate事件,本身也存在版本兼容隐患。 - 异步请求积压
你的定时器间隔仅为4秒,未做前一次请求是否完成的判断,一旦服务器查询接口响应变慢,大量未处理的Promise、回调函数和Embed实例会持续积压在内存中,进一步加重内存负担。
修复方案
- 移除
message事件的绑定,将定时查询逻辑放到客户端ready事件中,全局仅初始化一次定时任务 - 替换死循环+
setTimeout的实现,直接使用setInterval做周期查询,增加前序请求是否完成的判断,避免请求积压 - 复用Embed实例,减少重复创建对象的开销
修复后示例代码
// 全局标记,避免请求重叠 let isQuerying = false; client.on('ready', () => { console.log('客户端已就绪,启动状态定时查询'); // 每4秒执行一次查询 setInterval(async () => { if (isQuerying) return; // 上一次查询未完成则跳过 isQuerying = true; try { const response = await util.statusBedrock('ip', { port: port, timeout: 3800 }); const Embed = new Discord.MessageEmbed() .setColor('#62ff00') .setTitle('Server Status') .setAuthor('Made by ThatTheredstoner') .addField(':green_circle: Online', response.version) .addField('**Software/System**', response.software) .addField('Server IP', 'ip') .addField('Server Port', response.port) .addField('Gamemode', 'Survival ') .addField('**Latency**', response.roundTripLatency) .addField('Online Player', response.onlinePlayers) .addField('Player', response.players) .addField('Max Players', response.maxPlayers) .setTimestamp() .setFooter('footer'); const mesg = await client.channels.cache.get('channel').messages.fetch('message'); await mesg.edit(Embed); console.log(response); } catch (error) { console.log(error); const OEmbed = new Discord.MessageEmbed() .setColor('#ff0000') .setTitle('Server Status') .setAuthor('Powered with Redstone') .addField(':red_circle:', 'Offline') .addField('Server IP', 'ip') .setTimestamp() .setFooter('footer'); const mesg = await client.channels.cache.get('channel id').messages.fetch('message id'); await mesg.edit(OEmbed); } finally { isQuerying = false; } }, 4000); });
内容的提问来源于stack exchange,提问作者ThatTheredstoner
相关产品推荐
相关产品推荐

