No clear answer for "computations created outside a `createRoot` or `render` will never be disposed"
I spent 5+ hours today reading about, running experiments and trying to find out exactly what warning message:
computations created outside aactually means, but there is no definitive info. I get this message for some global createMemo, as well as expression inside thecreateRoot
orrender
will never be disposed
<Title>
component.
Global createMemo scenarios
in all three scenarios, signal and memos are created once globally.
In such a case, scenarios 'B' and 'C' produce the said message.
Question: for each of scenarios (A, B, C), does calling setNum
causes an extra memory leak?
Explanations are very appreciated, but please include definitive "yes/no" for each of A, B, C.
I tried running an experiment calling setNum
10M+ of times and I don't know how to interpret the results: Microsoft's Edge Memory (as seen in Task Manager) grows to 8+Gb even for scenario "A", but sometimes it grows, sometimes it doesn't, some times it grew uncontrollably to 30+ Gb. After pausing the execution, it does garbage collection (and I force it in DevTools) and memory usage settles to lower number, but it's still always a few Gb - way more than initially.12 Replies
Second group of scenarios
All
setInterval
are executed globally.
Similar question: which of A, B, C will cause memory leakage?
<Title> problem?
Finally, I have this line:
which specifically also seems to cause the same message.
When browsing the web, I stumbled somewhere that <Tasks>
causes this problem, but there was nothing specific and no suggested resolution.Creating signals won't cause memory leaks, neither setting signals. Signals are simple, independent objects
Memos created as global variables won't be disposed, but all global variables won't be GCed anyway, so they are not memory leaks
Creating both signal and memo in setInterval also won't cause memory leaks, because nothing references them. JS GC doesn't use reference counting, so they referencing each other won't prevent them to be GCed
Creating memos that depending on a global signal (or a signal being referenced by other variables), without Solid owner, will cause a memory leak. Because the memo adds itself to the signal's reaction list, causing the signal to reference it and keep it alive
For <Title>, it saves its children can execute later without owner (I had an issue that <Title>'s children can't read contexts in should belong to). Maybe it should capture the current owner and run its children in that. Anyway you can create a memo in your component and pass it to <Title>
Thanks for your case-by-case reply!
Just to confirm:
a) Warning "computations created outside a
createRoot
or render
will never be disposed" is not "you have a memory leak", but no more than a warning?
b) None of original 6 scenarios cause memory leak
c) This:
will cause memory leak?c. yes
when you see that warning if you did not intended for something to linger you are likely need to "track it" so it is cleaned up when the parts that depends on it is cleaned up
Yes to all three. Also
createRoot(() => createMemo(...))
suppresses the warning, but the memo still won't be disposed (or GCed)yes, it suppresses it, but also gives you a way to dispose of it
I think I understand: looking at the last 'c', it's clear where the leak comes from (since JavaScript doesn't have destructors similar to C++)
the leak comes from infinite interval
that keeps on creating memos
Yeah, I meant that in C++ you can auto-destroy stuff, which goes out-of-scope (in this case
numString
), but there is no such thing in JavaScript, so it needs to be managed manuallyyes.
but createMemo by nature is a "long running" primitive
and running in setInterval or setTimeout runs code in global scope( non trackable by solid)
generally, solid keep tracks of memo and other effects, and auto dispose when the part that created in your application is destructed.
if you see the warning it means you have to manually handle it yes.
when you don't. you know that solid is able to track it and auto destruct it like C++
So, a fixed number of such warnings at startup for global memos are ok, but such warnings appearing repeatedly is a memory leak. Got it
yeah, that will be a good indicator.
also if you want to see more how things work, or can work, you can check this playground.
https://playground.solidjs.com/anonymous/768d5d53-d453-44eb-9d96-2b0719998e89
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template