Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak when only using marshalling #30

Open
Matthiee opened this issue Nov 13, 2023 · 0 comments · May be fixed by #31
Open

Memory leak when only using marshalling #30

Matthiee opened this issue Nov 13, 2023 · 0 comments · May be fixed by #31
Labels
bug Something isn't working

Comments

@Matthiee
Copy link

Issue

When having code that returns data from VM -> Host, the memory used will keep on increasing each time the evalCode call is made.

Additional context

"quickjs-emscripten": "^0.23.0",
"quickjs-emscripten-sync": "^1.5.2",

We are using this package to marshal a lot of classes, objects, functions from the Host -> VM. Because of this, we are using a single long-lived QuickJsContext.

Our host needs to call methods on the instances of classes created inside the VM, these functions may return either simple data objects or Promise containing simple data and will use functions made available from the Host -> VM.

We have no use case for using the syncing functionality provided by this package.

It appears that because of the syncing capabilities of this package, memory is being retained by the QuickJsRuntime for each call made to the ´evalCode´ that needs to return some data.

What did I already try

Disable isHandleWrappable and isWrappable. While this appeared to work at first glance, it however doesn't work when the code is async/await. It also doesn't work when using moduleLoader.

Expected

No memory is being retained when not using the syncing capabilities.

Reproduce

  • memory no leak will log an increase of 948.
  • memory leak will log a number much higher.

If you change the amount of iterations of the arena.evalCode("globalThis.test.check()");, the memory used for the no leak scenario will remain at 948 while the leak scenario will keep on increasing for each iteration.

  test("memory no leak", async () => {
    const ctx = (await getQuickJS()).newContext();
    const arena = new Arena(ctx, { isMarshalable: true });

    const getMemory = () => {
      const handle = ctx.runtime.computeMemoryUsage();
      const mem = ctx.dump(handle);
      handle.dispose();
      return mem;
    };

    arena.evalCode(`globalThis.test = {
      check: () => {
        return {
          id: 'some id',
          data: 123
        };
      }
    }`);

    const memoryBefore = getMemory().memory_used_size as number;

    for (let i = 0; i < 10; i++) {
      const handle = ctx.unwrapResult(ctx.evalCode("globalThis.test.check()"));
     const data = ctx.dump(handle);
     handle.dispose();

     expect(data).toStrictEqual({id: 'some id', data: 123});
    }

    const memoryAfter = getMemory().memory_used_size as number;

    console.log("Allocation increased %d", memoryAfter - memoryBefore);

    arena.dispose();
    ctx.dispose();
  });

  test("memory leak", async () => {
    const ctx = (await getQuickJS()).newContext();
    const arena = new Arena(ctx, { isMarshalable: true });

    const getMemory = () => {
      const handle = ctx.runtime.computeMemoryUsage();
      const mem = ctx.dump(handle);
      handle.dispose();
      return mem;
    };

    arena.evalCode(`globalThis.test = {
      check: () => {
        return {
          id: 'some id',
          data: 123
        };
      }
    }`);

    const memoryBefore = getMemory().memory_used_size as number;

    for (let i = 0; i < 10; i++) {
      const data = arena.evalCode("globalThis.test.check()");
      expect(data).toStrictEqual({id: 'some id', data: 123});
    }

    const memoryAfter = getMemory().memory_used_size as number;

    console.log("Allocation increased %d", memoryAfter - memoryBefore);

    arena.dispose();
    ctx.dispose();
  });
@Matthiee Matthiee linked a pull request Nov 16, 2023 that will close this issue
@rot1024 rot1024 added the bug Something isn't working label Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants