microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
162.19k stars 28.55k forks source link

potential listener LEAK detected, having 185 listeners already. #211105

Open jrieken opened 4 months ago

jrieken commented 4 months ago

Testing #210961

event.ts:875 [72h] potential listener LEAK detected, having 185 listeners already. MOST frequent listener (8):
check @ event.ts:875
q @ event.ts:1056
M @ menuService.ts:395
q @ event.ts:1064
m @ notebookOutline.ts:217
renderElement @ notebookOutline.ts:182
renderElement @ abstractTree.ts:418
renderElement @ listWidget.ts:1249
Z @ listView.ts:940
(anonymous) @ listView.ts:876
transact @ rowCache.ts:80
Y @ listView.ts:867
ib @ listView.ts:1107
y @ event.ts:1156
z @ event.ts:1167
fire @ event.ts:1191
(anonymous) @ scrollableElement.ts:216
y @ event.ts:1156
fire @ event.ts:1187
n @ scrollable.ts:393
setScrollPositionNow @ scrollable.ts:303
R @ scrollableElement.ts:470
$ @ scrollableElement.ts:382
event.ts:876 Error
    at c.create (event.ts:889:25)
    at l.q [as onDidChange] (event.ts:1055:34)
    at Object.M [as onWillAddFirstListener] (menuService.ts:395:34)
    at f.q [as onDidChange] (event.ts:1064:20)
    at O.m (notebookOutline.ts:217:44)
    at O.renderElement (notebookOutline.ts:182:9)
    at A.renderElement (abstractTree.ts:418:17)
    at Y.renderElement (listWidget.ts:1249:13)
    at m.Z (listView.ts:940:13)
    at listView.ts:876:11
    at E.transact (rowCache.ts:80:4)
    at m.Y (listView.ts:867:14)
    at m.ib (listView.ts:1107:9)
    at n.y (event.ts:1156:13)
    at n.z (event.ts:1167:9)
    at n.fire (event.ts:1191:9)
    at d.value (scrollableElement.ts:216:19)
    at n.y (event.ts:1156:13)
    at n.fire (event.ts:1187:9)
    at I.n (scrollable.ts:393:18)
    at I.setScrollPositionNow (scrollable.ts:303:8)
    at n.setScrollPosition (scrollableElement.ts:619:21)
    at m.setScrollTop (listView.ts:1030:26)
    at X.reveal (listWidget.ts:1909:14)
    at ie.reveal (abstractTree.ts:2989:14)
    at d.H [as value] (outlinePane.ts:332:11)
    at n.y (event.ts:1156:13)
    at n.z (event.ts:1167:9)
    at n.fire (event.ts:1191:9)
    at d.value (notebookOutline.ts:375:24)
    at n.y (event.ts:1156:13)
    at n.z (event.ts:1167:9)
    at n.fire (event.ts:1191:9)
    at u.r (notebookOutlineProvider.ts:298:22)
    at notebookOutlineProvider.ts:57:79
    at async.ts:364:13
check @ event.ts:876
q @ event.ts:1056
M @ menuService.ts:395
q @ event.ts:1064
m @ notebookOutline.ts:217
renderElement @ notebookOutline.ts:182
renderElement @ abstractTree.ts:418
renderElement @ listWidget.ts:1249
Z @ listView.ts:940
(anonymous) @ listView.ts:876
transact @ rowCache.ts:80
Y @ listView.ts:867
ib @ listView.ts:1107
y @ event.ts:1156
z @ event.ts:1167
fire @ event.ts:1191
(anonymous) @ scrollableElement.ts:216
y @ event.ts:1156
fire @ event.ts:1187
n @ scrollable.ts:393
setScrollPositionNow @ scrollable.ts:303
R @ scrollableElement.ts:470
$ @ scrollableElement.ts:382
jrieken commented 4 months ago

Looks like this is coming from here: https://github.com/microsoft/vscode/blob/a49c81edea6647684eee87d204e50feed9c455f6/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts#L217

Setting up a listener per rendered element isn't great, it's better to have one and share it with the elements

jrieken commented 4 months ago

This is the notebook I am testing with: slow.ipynb.txt

jrieken commented 4 months ago

same/related https://github.com/microsoft/vscode/issues/211112

rebornix commented 2 months ago

This seems to be a general issue for tree menus on large screens. When we support action contributions for tree elements, a menu is created for each visible tree element, and each menu registers a listener to HiddenStates change:

https://github.com/microsoft/vscode/blob/6ab3a15691ff9a1aa619a53d9dcd29c0b53d76a1/src/vs/platform/actions/common/menuService.ts#L395-L397

Since each tree menu registers an onChange event listener, the HiddenStates change emitter is no longer lazy.

image

This issue can be easily reproduced on a large screen with both the outline view and the timeline view opened for a relatively large notebook. Each tree has 50+ visible tree elements (with at least one menu for each), quickly hitting the threshold of 175.


The above analysis explains why this happens. I'm wondering how we can improve this given the constraint that each tree element has its own context, preventing the use of a shared event emitter/listener. One idea is to register the menu change listener lazily: update the actions and register the listener only when the user hovers over the item for the first time.

jrieken commented 2 months ago

This seems to be a general issue for tree menus on large screens. When we support action contributions for tree elements, a menu is created for each visible tree element

Pretty sure @alexr00 already fixed this for contributed trees. The menu is only created when a tree element is active. Tho, it might be that the code bunny has spread this pattern onto other trees, document outline has no actions, unsure about notebook outline (tho the stacktrace won't lie) and timeline has.

One idea is to register the menu change listener lazily: update the actions and register the listener only when the user hovers over the item for the first time.

As said, this is kinda how it was fixed for custom trees. Not the menu is lazy but the menu isn't created to begin with

alexr00 commented 2 months ago

I ended up having to revert the fix for contributed trees as it broke tree checkboxes: https://github.com/microsoft/vscode/pull/217170

The tree doesn't actually care about the hidden states, so maybe we could resurrect https://github.com/microsoft/vscode/pull/214132

jrieken commented 2 months ago

The tree doesn't actually care about the hidden states, so maybe we could resurrect https://github.com/microsoft/vscode/pull/214132

I don't think that helps - it means less listeners for hidden states but the equal amount of listeners for the context key service. Leak blaming isn't symmetric but sooner or later the menus/trees will be blamed for having to many CKS listeners

alexr00 commented 2 months ago

New, and I hope improved, contributed tree change coming with https://github.com/microsoft/vscode/pull/219964. My change won't impact this issue though as it's local to contributed trees. However, the ability to get menu contexts which I'm adding may be of use to you.