Skip to content

Module memory leaks on every execution of widget #613

Open
@jleibs

Description

@jleibs

It appears that every time we execute our widget, a new copy of the module is instantiated, and subsequently leaked.

You can replicate this with a module that includes a large const such as:

import anywidget
import traitlets

class LeakyWidget(anywidget.AnyWidget):
    _esm = """
    const buffer = new ArrayBuffer(100000000);
    
    function render({ model, el }) {
      let div = document.createElement("div");
      
      div.innerHTML = `Buffer is is ${buffer.byteLength} bytes.`;
      
      el.classList.add("leaky-widget");
      el.appendChild(div);
    }
    export default { render };
    """
    _css = """
    .leaky-widget button { background-color: #ea580c; }
    """
    value = traitlets.Int(0).tag(sync=True)

Repeatedly executing LeakyWidget() in a cell will leak ~100MB per run.

You can see this in a browser tool inspector by taking snapshots after each execution of the cell and seeing newly created ModuleEnvironmentObjects:
image

Ideally, we would have some mechanism to simply cache and re-use the same module across all widget instances, but it would be acceptable for them to at least get freed correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions