Closed huodoushigemi closed 1 week ago
I'm not sure this is a memory leak. If I set the Playground to PROD mode, the VClass
instances are no longer retained in memory.
I believe the reason they're being retained is due to the proxying used to expose variables to the template in dev. In production mode, the variable scope
is eligible for GC, so list
and the VClass
instances are no longer present.
But perhaps using production mode is 'cheating', in the sense that I'm bypassing what the reproduction was trying to show.
Perhaps the intention was just to illustrate that stopping an EffectScope
doesn't free the effects it contains?
But I'm not sure whether that is necessarily a problem either. If I might use an analogy, when a component instance is unmounted we do a certain amount of teardown, but we don't teardown everything. A lot of the internals are left intact and it's down to the garbage collector to free up that memory. If someone retains an external reference to the component instance then those internals will still show in a memory dump, but it isn't really a leak.
I think what's happening here is essentially the same thing. The EffectScope
is only doing a limited amount of internal teardown, then relying on GC to do the rest. If you retain a reference to the EffectScope
instance then you'll get some of the internals with it.
It isn't immediately clear to me whether EffectScope
should be doing more internal teardown, or whether it's just not valid to retain a reference to it after it's been stopped.
Like @skirtles-code pointed out, I don't think this technically qualifies as a leak. But considering standalone usage of @vue/reactivity
, it's still nice to release nested resources on stop in case the scope
reference is retained for some reason.
Vue version
3.5.12
Link to minimal reproduction
https://play.vuejs.org/#eNp9UkFuwjAQ/MrKlzpSFEDtCQESRUhtD21Vqp58icIGQh3bsh2gQvl71w6hHCpySOKZ2fHs2ic2NybbN8jGbOIKWxkPDn1jZkJVtdHWwwkslikccl9sU8CyxMKvCm0QWiitruGOyu+EEqqQuXPwtYifE7QR08qRZdRPr6t5EuhIZLZRnCcwncFJKICuRlb0mobN+dza/IePhsNhkpWVlDzJ6tzwc43Cw3lTntATbHsP57Uhj5idB8MUzvtAS0KAwSBqQpgA9IF6bDLoZkLToIXH2sjcI60AJtvR7Aml1HDQVq4nA1qHgouIpcyTmyqrTbZzWtGEY3eCFbo2lUT7ZnxFMQUbd30HLifHw0vEvG0w7fFii8X3P/jOHQMm2LtFh3aPgl04n9sN+o5erl7xSP8XstbrRpL6BvmBTssmZOxkj41aU+wrXUz7HO9JpTafbnn0qFzfVAgalG3UC0b3ZHGj9b+499lDrKNDYe0vcNPd8w==
Steps to reproduce
Start chrome Open the linked SFC Playground Open devtools > Memory Invoke garbage collection (click on trash) Create snapshot In the created snapshot, filter for VClass objects
What is expected?
list
should be garbage collectedWhat is actually happening?
list
should be garbage collectedSystem Info
No response
Any additional comments?
No response