FileEditor memory leak

已回答

I implemented FileEditorProvider, and the page returned an EditorTextField. Here is my code. When I closed the idea, an error occurred

public class HTTPEditor implements FileEditor {
    private final VirtualFile virtualFile;
    private Project project;
    private EditorTextField editorTextField;

    public HTTPEditor(Project project, @NotNull VirtualFile file) {
        this.project = project;
        this.virtualFile = file;
        editorTextField = new EditorTextField("a");
    }

    @Override
    public @NotNull JComponent getComponent() {
        return editorTextField;
    }

    @Override
    public @Nullable JComponent getPreferredFocusedComponent() {
        return null;
    }

    @Override
    public @Nls(capitalization = Nls.Capitalization.Title) @NotNull String getName() {
        return "a";
    }

    @Override
    public void setState(@NotNull FileEditorState state) {

    }

    @Override
    public boolean isModified() {
        return false;
    }

    @Override
    public boolean isValid() {
        return true;
    }

    @Override
    public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {

    }

    @Override
    public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {

    }

    @Override
    public void dispose() {
        Disposer.dispose(this);
    }

    @Override
    public <T> @Nullable T getUserData(@NotNull Key<T> key) {
        return null;
    }

    @Override
    public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {

    }

    @Override
    public VirtualFile getFile() {
        return this.virtualFile;
    }
}

error:

See https://jetbrains.org/intellij/sdk/docs/basics/disposers.html for more details.
The corresponding Disposer.register() stacktrace is shown as the cause:

java.lang.RuntimeException: Memory leak detected: 'com.intellij.openapi.editor.impl.view.EditorView@596c4db1' of class com.intellij.openapi.editor.impl.view.EditorView is registered in Disposer but wasn't disposed.
Register it with a proper parentDisposable or ensure that it's always disposed by direct Disposer.dispose call.
See https://jetbrains.org/intellij/sdk/docs/basics/disposers.html for more details.
The corresponding Disposer.register() stacktrace is shown as the cause:

	at com.intellij.openapi.util.ObjectNode.assertNoChildren(ObjectNode.java:41)
	at com.intellij.openapi.util.ObjectTree.assertIsEmpty(ObjectTree.java:210)
	at com.intellij.openapi.util.Disposer.assertIsEmpty(Disposer.java:232)
	at com.intellij.openapi.util.Disposer.assertIsEmpty(Disposer.java:227)
	at com.intellij.openapi.application.impl.ApplicationImpl.disposeContainer(ApplicationImpl.java:230)
	at com.intellij.openapi.application.impl.ApplicationImpl.disposeSelf(ApplicationImpl.java:247)
	at com.intellij.openapi.application.impl.ApplicationImpl.doExit(ApplicationImpl.java:676)
	at com.intellij.openapi.application.impl.ApplicationImpl.exit(ApplicationImpl.java:629)
	at com.intellij.openapi.application.impl.ApplicationImpl.exit(ApplicationImpl.java:618)
	at com.intellij.openapi.application.ex.ApplicationEx.exit(ApplicationEx.java:75)
	at com.intellij.openapi.wm.impl.CloseProjectWindowHelper.quitApp(CloseProjectWindowHelper.kt:66)
	at com.intellij.openapi.wm.impl.CloseProjectWindowHelper.windowClosing(CloseProjectWindowHelper.kt:44)
	at com.intellij.openapi.wm.impl.ProjectFrameHelper$2.windowClosing(ProjectFrameHelper.java:232)
	at java.desktop/java.awt.AWTEventMulticaster.windowClosing(AWTEventMulticaster.java:357)
	at java.desktop/java.awt.Window.processWindowEvent(Window.java:2107)
	at java.desktop/javax.swing.JFrame.processWindowEvent(JFrame.java:298)
	at java.desktop/java.awt.Window.processEvent(Window.java:2066)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5022)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2802)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854)
	at com.intellij.openapi.wm.impl.customFrameDecorations.header.CustomHeader.close(CustomHeader.kt:222)
	at com.intellij.openapi.wm.impl.customFrameDecorations.header.CustomHeader$myCloseAction$1.invoke(CustomHeader.kt:219)
	at com.intellij.openapi.wm.impl.customFrameDecorations.header.CustomHeader$myCloseAction$1.invoke(CustomHeader.kt:36)
	at com.intellij.openapi.wm.impl.customFrameDecorations.header.CustomHeader$CustomFrameAction.actionPerformed(CustomHeader.kt:229)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
	at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
	at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:297)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6648)
	at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3392)
	at java.desktop/java.awt.Component.processEvent(Component.java:6413)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5022)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2802)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:781)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:730)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:724)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:754)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:752)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:751)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:898)
	at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.java:820)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:743)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$6(IdeEventQueue.java:439)
	at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:791)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$7(IdeEventQueue.java:438)
	at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:113)
	at com.intellij.ide.IdeEventQueue.performActivity(IdeEventQueue.java:604)
	at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:436)
	at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:881)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:484)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)
Caused by: java.lang.Throwable
	at com.intellij.openapi.util.ObjectNode.<init>(ObjectNode.java:24)
	at com.intellij.openapi.util.ObjectNode.findOrCreateChildNode(ObjectNode.java:165)
	at com.intellij.openapi.util.ObjectTree.register(ObjectTree.java:51)
	at com.intellij.openapi.util.Disposer.register(Disposer.java:117)
	at com.intellij.openapi.editor.impl.view.EditorView.<init>(EditorView.java:96)
	at com.intellij.openapi.editor.impl.EditorImpl.<init>(EditorImpl.java:493)
	at com.intellij.openapi.editor.impl.EditorFactoryImpl.createEditor(EditorFactoryImpl.java:202)
	at com.intellij.openapi.editor.impl.EditorFactoryImpl.createEditor(EditorFactoryImpl.java:157)
	at com.intellij.ui.EditorTextField.createEditor(EditorTextField.java:591)
	at com.intellij.ui.EditorTextField.initEditorInner(EditorTextField.java:458)
	at com.intellij.ui.EditorTextField.initEditor(EditorTextField.java:443)
	at com.intellij.ui.EditorTextField.lambda$new$0(EditorTextField.java:158)
	at java.desktop/java.awt.Component.processHierarchyEvent(Component.java:6815)
	at java.desktop/java.awt.Component.processEvent(Component.java:6434)
	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5022)
	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854)
	at java.desktop/java.awt.Component.addNotify(Component.java:7119)
	at java.desktop/java.awt.Container.addNotify(Container.java:2793)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4847)
	at com.intellij.ui.EditorTextField.addNotify(EditorTextField.java:886)
	at java.desktop/java.awt.Container.addNotify(Container.java:2804)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4847)
	at java.desktop/java.awt.Container.addNotify(Container.java:2804)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4847)
	at java.desktop/java.awt.Container.addNotify(Container.java:2804)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4847)
	at java.desktop/java.awt.Container.addNotify(Container.java:2804)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4847)
	at java.desktop/java.awt.Container.addImpl(Container.java:1150)
	at com.intellij.ui.tabs.impl.JBTabsImpl.addImpl(JBTabsImpl.java:2722)
	at java.desktop/java.awt.Container.add(Container.java:440)
	at com.intellij.ui.tabs.impl.JBTabsImpl.updateContainer(JBTabsImpl.java:2693)
	at com.intellij.ui.tabs.impl.JBTabsImpl.executeSelectionChange(JBTabsImpl.java:1531)
	at com.intellij.ui.tabs.impl.JBTabsImpl$14.run(JBTabsImpl.java:1487)
	at com.intellij.openapi.fileEditor.impl.EditorTabbedContainer.lambda$new$1(EditorTabbedContainer.java:123)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:210)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:174)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:164)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:150)
	at com.intellij.openapi.fileEditor.impl.EditorTabbedContainer.lambda$new$2(EditorTabbedContainer.java:121)
0

Please share full code. What is the file editor provider implementation?

0
public class HttpFileEditorProvider implements FileEditorProvider, DumbAware {
    private static String EDITOR_TYPE_ID = "xxxx";

    @Override
    public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
        return file.getFileType().getDefaultExtension().equalsIgnoreCase("xxxx")
                && file instanceof CoolHTTPRequestVirtualFile;
    }

    @Override
    public @NotNull FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
        return new HTTPEditor(project, file);
    }

    @Override
    public @NotNull @NonNls String getEditorTypeId() {
        return EDITOR_TYPE_ID;
    }

    @Override
    public @NotNull FileEditorPolicy getPolicy() {
        return FileEditorPolicy.HIDE_DEFAULT_EDITOR;
    }
}
          ApplicationManager.getApplication().runWriteAction(() -> {
                VirtualFile virtualFile = createNewFile();
                if (virtualFile != null) {
                    FileEditorManager.getInstance(project).openFile(virtualFile, true);
                }
            });

When I close the tab, I will not get an error when closing the idea, but when I close the idea when the tab is open, I will get an error

0

This code looks strange:

@Override
public void dispose() {
    Disposer.dispose(this);
}

It's probably never called, as your editor is not registered in the Disposer tree.

I suggest registering your editor as disposable with a project-leveI service as parent. In the dispose() method, you should dispose of any resources the editor holds.

0

How to register an editor to the Disposer tree?,setDisposedWith() method doesn't work

0

请先登录再写评论。