monaco-editor icon indicating copy to clipboard operation
monaco-editor copied to clipboard

[Bug] Memory leaking when disposing Diff editor

Open samirzubi-db opened this issue 1 year ago • 3 comments

Reproducible in vscode.dev or in VS Code Desktop?

  • [X] Not reproducible in vscode.dev or VS Code Desktop

Reproducible in the monaco editor playground?

Monaco Editor Playground Link

No response

Monaco Editor Playground Code

No response

Reproduction Steps

I wrote a small application demonstrating the issue: You can find it on the following link: https://zd9n67.csb.app/ Code: https://codesandbox.io/p/sandbox/react-typescript-forked-zd9n67

Actual (Problematic) Behavior

Diff editor does not dispose correctly after being removed from the dom. The regular editor component does not have this issue.

Initial load initial_render

Second memory snapshot second_take

Third memory snapshot third_take

Fourth memory snapshot fourth_take

The memory constantly grows as the diff editor is not properly disposed of. Form my investigation I could see that the Emitter and InteractionEmitter are constantly growing without being disposed in the monaco-editor/esm/vs/editor/browser/widget/codeEditor/codeEditorWidget.js file. Also a lot of detached canvas dom elements like: <canvas class="original diffOverviewRuler" ...

Expected Behavior

Diff editor gets removed properly and does not cause a memory leak.

Additional Context

We started observing the issue in the 0.44.0 version of monaco-editor as the earlier versions don't seem to have this problem. The example is for the latest version 0.51.0

samirzubi-db avatar Aug 27 '24 14:08 samirzubi-db

Probably would be a good idea to write a unit test in the monaco editor library to test against memory leaks in the future?

alexanderwu-db avatar Aug 27 '24 17:08 alexanderwu-db

I've submitted a fix in the vscode repo in case anyone needs to fix this in their codebase.

samirzubi-db avatar Oct 07 '24 14:10 samirzubi-db

I'm not sure if this is directly related to a bug, but I encountered a strange behavior when switching from a DiffEditor to a regular Editor. After disposing a DiffEditor and then creating a regular Editor, the arrow keys (← →) start moving the cursor two characters instead of one.

Here's a minimal example to reproduce the issue. Please try it in the Monaco Playground:

let editor = null;
let diffEditor = null;

function disposeEditors() {
    monaco.editor.getEditors().forEach(e => e.dispose());
    monaco.editor.getModels().forEach(m => m.dispose()); 
    editor = null;
    diffEditor = null;
}

function initializeEditor(content = "") {
    require(['vs/editor/editor.main'], function () {
		disposeEditors();
        const container = document.getElementById('container');
        container.innerHTML = ""; 
        editor = monaco.editor.create(container, {
            value: content,
        });
    });
}

function initializeDiffEditor(originalContent, modifiedContent) {
    require(['vs/editor/editor.main'], function () {
		disposeEditors();
        const container = document.getElementById('container');
        container.innerHTML = ""; 
        diffEditor = monaco.editor.createDiffEditor(container, {
        });
        const originalModel = monaco.editor.createModel(originalContent, 'plaintext');
        const modifiedModel = monaco.editor.createModel(modifiedContent, 'plaintext');
        diffEditor.setModel({ original: originalModel, modified: modifiedModel });
    });
}

initializeEditor("AABBAABB");
initializeDiffEditor("AAAA", "BBBB")
initializeEditor("AABBAABB");

Osg-Junue avatar May 30 '25 17:05 Osg-Junue

@samirzubi-db, I have checked. Only by adding this._codeEditorService.removeDiffEditor(this);this._onDidDispose.fire();super.dispose() in diffEditorWidget.js- will not work, What I see here in abstractCodeEditorService.js under Services, There is no implementation for removeDiffEditor, I have added removeDiffEditor(editor) { if (delete this._diffEditors[editor.getId()]) { this._onDiffEditorRemove.fire(editor); } } Now, I has started working. I am using monaco editor latest version.

Image Image

Swapnamoy4345 avatar Jul 22 '25 07:07 Swapnamoy4345

I'm not sure if this is directly related to a bug, but I encountered a strange behavior when switching from a DiffEditor to a regular Editor. After disposing a DiffEditor and then creating a regular Editor, the arrow keys (← →) start moving the cursor two characters instead of one.

@Osg-Junue, I came across the same behavior. What I found is that in accessibleDiffViewer keys are attached as events to the root DOM node. And it seems it is not cleared well when disposing. When I removed some event listeners manually in DevTools, it helped.

akondratsky avatar Jul 28 '25 14:07 akondratsky

I still see some leak on the latest preview 0.55.0-dev-20251105 , using the codesandbox example linked above after 2000 iterations:

Image

connor4312 avatar Nov 05 '25 23:11 connor4312