-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unbounded memory growth in Flutter application - due to missing old-space GC #43770
Comments
We can add a test like this to the devicelab, which can track memory usage over the life of the process. |
@mkustermann This example behaves differently on my device, with a mixture of idle and non-idle GCs, including idle old-space GC. Could you send me the timeline captured from your device? NotifyIdle will already ignore the deadline if old-space is sufficiently full, so I suspect something else has gone wrong; perhaps the threshold has been corrupted or the force-growth bit got stuck. |
@rmacnak-google For ease of running I use Flutter's desktop embedding:
It's sometimes a little hard to trigger this behavior. I've rebased now and got one trace. In that trace it seems we are triggering old space collections. Though we still cause unbounded memory growth. It might be that the old space collector cannot keep pace. |
It looks like the write-barrier elimination bug you found was effectively creating a memory leak by its corruption in this example. I observed unbounded growth even though old-space GC was happening, the heap not shrinking even with forced compaction, and heap snapshots also reporting the heap as all used. Some added Dart code observed cycles in the linked list. With the write-barrier fix patched in, I no longer observe the unbounded growth and the cycles disappear. Both before and after the writer-barrier fix, I don't observe the scenario where old-space GC doesn't happen, so that seems like a separate issue. |
@rmacnak-google The example was flakily crashing for me, which lead me to the bug in write-barrier elimination. I've tried now with the fix and it seems on my Mac the memory growth doesn't happen anymore so it's probably indeed due to the bug. |
If there is a GC-triggering instruction between array allocation and store into array we cannot omit the barrier. This worked for stores where the receiver is a direct array allocation, but not if it's a phi. Closes #43786 Closes #43770 Change-Id: I28de29cf85842a9d3ae3189bb8e6426969fe4279 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167570 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
If there is a GC-triggering instruction between array allocation and store into array we cannot omit the barrier. This worked for stores where the receiver is a direct array allocation, but not if it's a phi. Closes #43786 Closes #43770 Change-Id: I28de29cf85842a9d3ae3189bb8e6426969fe4279 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167570 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
The following flutter application runs an animation. When building each frame we do new memory allocations and make older objects unreachable. The live memory at any given point in time should be <100 MB, though the process will eventually OOM due to unbounded memory growth:
Most likely this happens due to missing start of old space collections during the
Dart_NotifyIdle
calls from flutter engine:Here we can see that every
Dart_NotifyIdle
will cause a scavenge that almost exhausts the 16 ms limit - which might be why we fail to start old space collection.=> We should ensure to have tests for our heuristics - effectively adding regression tests for such bugs.
/cc @rmacnak-google Maybe you could take a look?
/cc @dnfield Since it's related to idle notification. Do you have any suggestions how to add memory tests on flutter side?
The text was updated successfully, but these errors were encountered: