oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.3k stars 2.78k forks source link

Streams memory leak #12198

Open oguimbal opened 4 months ago

oguimbal commented 4 months ago

What version of Bun is running?

1.1.17+bb66bba1b

What platform is your computer?

Darwin 23.1.0 arm64 arm

What steps can reproduce the bug?

Execute the below code, and watch memory usage:


setInterval(() => {
    Bun.gc(true);
}, 100);

const p = Bun.spawn(['cat'], {
    stdin: 'pipe',
    stdout: 'pipe',
})

const r = p.stdout.getReader()
while (true) {
    const buf = new Uint8Array(1_000_000);
    await p.stdin.write(buf);

    let i = 0;
    while (true) {
        const { value } = await r.read();
        i += value?.length ?? 0;
        if (i >= buf.length) {
            break;
        }
    }
}

What is the expected behavior?

Each iteration just wait until the buffer is streamed through cat, so I'd expect memory not to increase.

What do you see instead?

CPU 100%, memory increases rapidly.

Interestingly enough, when every byte has been streamed, if I add another .read() (which rightfuly returns no data), the memory leak disapears:


setInterval(() => {
    Bun.gc(true);
}, 100);

const p = Bun.spawn(['cat'], {
    stdin: 'pipe',
    stdout: 'pipe',
})

const r = p.stdout.getReader()
while (true) {
    const buf = new Uint8Array(1_000_000);
    await p.stdin.write(buf);

    let i = 0;
    while (true) {
        const { value } = await r.read();
        i += value?.length ?? 0;
        if (i >= buf.length) {
           // 👉  this fixes the leak ! (and never throws)
            const { value: value2 } = await r.read();
            if (value2?.length) {
                throw new Error('Expected EOF');
            }
            break;
        }
    }
}

Additional information

This issue is kind of linked to #12194 (which I discovered investigating this leak)

Jarred-Sumner commented 3 weeks ago

Confirmed I am able to reproduce this memory leak in Bun v1.1.32