nodejs / nodejs/node

AbortSignal.any() causes memory leak

オープン
#54,614 コメント 12 件 リアクション 6 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

abortcontroller memory
主要言語
JavaScript
スター
122k
フォーク
37.4k
平均マージ
4日 3時間
マージ済み PR(30日)
272

説明

Version

v22.6.0

Platform
Microsoft Windows NT 10.0.22631.0 x64
Linux ****** 4.4.0-22621-Microsoft #3672-Microsoft Fri Jan 01 08:00:00 PST 2016 x86_64 x86_64 x86_64 GNU/Linux
Subsystem

https://nodejs.org/api/globals.html#class-abortsignal

What steps will reproduce the bug?

Run this and watch memory usage.

const formatMemoryUsage = (data) => `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;

let memoryData = process.memoryUsage();
console.log('Mem before loop', formatMemoryUsage(memoryData.rss));

for (let i = 0; true; i++) {
    const abortController = new AbortController();
    const signal = abortController.signal;
    const composedSignal = AbortSignal.any([signal]);

    if (i === 1000000) {
        break;
    }
}

memoryData = process.memoryUsage();
console.log('Mem after 1 million iteration', formatMemoryUsage(memoryData.rss));

This is what I get on my local machine
image

How often does it reproduce? Is there a required condition?

Always reproducible as far as I can tell

What is the expected behavior? Why is that the expected behavior?

Memory post loop execution should be fairly equivalent to the first log but somehow the const composedSignal = AbortSignal.any([signal]); does not get cleaned up from memory, I would expect this to get cleaned properly or if this is the intended behavior to have a clear warning in the documentation.

What do you see instead?

We see a memory leak that will eventually lead to an out of memory error.

Additional information

This has been tested on Node 22.6 on different machine and both Windows + Unix versions. Happy to provide more details if needed

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

issue に記載されている AbortSignal.any() のエントリーポイントから始め、提供された JavaScript の再現コードを Node.js で実行して、メモリ増加を確認します。合成されたシグナルが入力シグナルをどのように保持しているかを追跡し、それらの参照をいつ解放すべきかを判断します。単一シグナルの合成を繰り返し作成しても持続的なメモリ増加が発生しなくなり、再現コードを使用して動作を検証できれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
javascript
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
55/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。