Skip to content

SourceTextModule leaks memory when context is used #50113

@Havunen

Description

@Havunen

Version

21.0.0-nightly20231008fce8fbadcd

Platform

Microsoft Windows NT 10.0.22621.0 x64

Subsystem

No response

What steps will reproduce the bug?

Create two or more SourceTextModules and a SyntheticModule and link them together using a shared context (vm.createContext())

https://github.com/Havunen/nodejs-memory-leak

import {SourceTextModule, SyntheticModule, createContext} from 'vm';

async function link() {
    // Having a shared context leaks nodejs memory
    let context = createContext()
    const module = new SourceTextModule(`
        import foo from 'foo';
        
        export default {a: new Array(100000).fill('-')};
    `, {
        context,
        identifier: ''
    });
    const subModule = new SourceTextModule(`
        import asd from 'asd.json';

        export default asd;
    `, {
        context,
        identifier: 'foo'
    })
    const jsonModule = new SyntheticModule(
        ['default'],
        function () {
            // mimic some large file
            this.setExport('default', {a: new Array(100000).fill('-')});
        },
        {
            context,
            identifier: 'asd.json'
        }
    )

    await subModule.link(() => jsonModule)
    await module.link(() => subModule)

    await module.evaluate();

    // UN-COMMENT THIS LINE TO FIX THE LEAK?? wtf...
    context = null

    return module;
}

for (let i = 0; i < 100000; i++) {
    if (i % 100 === 0) {
        console.log("iterations" + i)
    }
    await link();
}

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

100%

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

NodeJs should not leak memory because the context object goes out of scope and should get garbage collected and all the modules associated with it.

What do you see instead?

The memory grows and grows depending on a number of modules and size of their data until nodejs fails to OOM.

Additional information

Note: Manually setting the context object null in JS side fixes the leak, but that should not be required

Metadata

Metadata

Assignees

No one assigned

    Labels

    vmIssues and PRs related to the vm subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions