Open jrieken opened 4 months ago
I am somewhat confused about vs/workbench/contrib/debug/browser/debugProgress.ts
, since those listeners are added to a disposable array kept in an IWorkbenchContribution
, which I would not expect to get disposed until the workbench is shutting down, and never forgotten about. (Nothing fancy going on, the two listeners are pushed to the disposable array in the contributing constructor and the array is never again modified before it's disposed)
edit: oh, I see, workbench contributions aren't actually disposables/disposed of. All of debug's "leaking listeners" are from workbench contributions or contributions that share the same lifecycle. I guess I can manually listen to the ILifecycleService.onWillShutDown and dispose listeners right before the workbench shuts down, but this seems like extra code size and computation for not much purpose...
I guess I can manually listen to the ILifecycleService.onWillShutDown and dispose listeners right before the workbench shuts down, but this seems like extra code size and computation for not much purpose...
Maybe or we make it a thing of workbench contributions, e.g probe if they "implement" disposable do that for all of them by default. @bpasero Opinions?
If I had to pick, I would rather not let contributions listen to the shutdown but do this from 1 listener from the contributions registry.
But then: whats the point of disposing on shutdown? Its not consistently applied, mainly because we know the JS context goes away anyway, so there is no way something can leak beyond that?
+ @meganrogge for task.contribution.ts
But then: whats the point of disposing on shutdown? Its not consistently applied, mainly because we know the JS context goes away anyway, so there is no way something can leak beyond that?
To me it's less about unloading JS but to have the theoretical possibility to shutdown the workbench and have it leave no traces, e.g no more DOM nodes, no more listener etc. So, that everything can be GC'ed and that we could restart the workbench in a different configuration, e.g with different contribution etc
🔈 fyi everyone: this list is now updated without auto-tracked workbench contributions but also with leaks from the main process and the EH
I think some are wrongly reported, for example:
Where we pass in the disposables array to store into.
I think some are wrongly reported, for example:
They leak because this is a workbench contribution but it doesn't implement a dispose
method. Therefore it get's GC'ed and the subscriptions are lost.
Ah yes, true!
The leaks found in debug's statusBarColorProvider and debugLifecycle are workbench contributions but are still tracked here
The leaks found in debug's statusBarColorProvider and debugLifecycle are workbench contributions but are still tracked here
@connor4312 Both look like legit leaks to me:
statusBarColorProvider
passes the disposable store as this argument (so no store to track)debugLifecycle
calling onBeforeShutdown
return a disposable which isn't trackedOh, I see. That's a nasty mixup. I'll add a check for that (passing a DisposableStore as a thisArg) since that should never be intended/
Edit: looks like that was the only place that mixup happened in a basic sanity test of the workbench
ping @aeschli @joyceerhl @joaomoreno
The 'leaks' in colorUtils. iconRegistry and tokenClassificationRegistry come from wiring registries: registering & updating the JSON schema registry with schemas describing known colors, icons and semantic tokens.
The registries are all globals and registries don't get disposed.
Is there a better way to structure this?
@aeschli Good question and not really sure of a good suggestion. Maybe it is already wrong that registries fire events all together. Should they be "done and dusted" after code loading and then read into some service which does more complex things?
The following is a list of code locations at which an event listener is added but the subscription (e.g the disposable that's being returned) is getting lost (garbage collected before disposal). This means the listener is question cannot be removed anymore and therefore it is a leak.
You can enable these warnings via
src/vs/base/common/event.ts#_enableListenerGCedWarning