这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Avoid calling Dart_HintFreed more than once every five seconds #25827

Merged
merged 7 commits into from
May 3, 2021

Conversation

dnfield
Copy link
Contributor

@dnfield dnfield commented Apr 28, 2021

This is to fix flutter/flutter#80702

I believe this approach makes sense because:

  • We should avoid triggering the VM to GC too frequently
  • Dart_HintFreed has no effect until the next Dart_NotifyIdle call.
  • We don't want to use a delayed task for that, since calling the Dart API requires isolate scope and would also require a mutex around the hint_freed related variables.

I picked 5 seconds somewhat arbitrarily. It still means we'd be running a GC at least every five seconds when animating a gif.

I created a devicelab benchmark for this, but it isn't quite reporting the right values to Skia perf yet. I will fix that before marking this as ready for review, but wanted to get feedback on the approach here in the mean time.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.
  • The reviewer has submitted any presubmit flakes in this PR using the engine presubmit flakes form before re-triggering the failure.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@google-cla google-cla bot added the cla: yes label Apr 28, 2021
@zanderso
Copy link
Member

Will platform low-memory signals override the 5-second delay?

@dnfield
Copy link
Contributor Author

dnfield commented Apr 29, 2021

Platform low memory signals end up calling Dart_NotifyLowMemory, which basically forces a GC ASAP. Different API path.

@dnfield
Copy link
Contributor Author

dnfield commented Apr 29, 2021

Hm. I might have a better solution framework side that would let us just not call Dart_HintFreed when images are released anyway.

@dnfield
Copy link
Contributor Author

dnfield commented Apr 30, 2021

Ahhhh this failure isn't a flake haha.

We call hint freed less often now. Argh. I'll have to think about this some more probably on monday.

@dnfield
Copy link
Contributor Author

dnfield commented May 3, 2021

Ok - the change here is to make sure we don't reset the timer if we didn't actually have any bytes to hint freeing, since that also is effectively a no-op.

@dnfield dnfield marked this pull request as ready for review May 3, 2021 17:03
Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, you just need a test that checks the 5 second rule. Maybe make the 5 seconds a constant you can build the test around to make sure it's not so fragile.

@@ -299,4 +302,44 @@ TEST_F(EngineTest, PassesLoadDartDeferredLibraryErrorToRuntime) {
});
}

TEST_F(EngineTest, NotifyIdleMoreThanOncePerFiveSeconds) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you want to show a timedelta that is less that 5 seconds so you can show it doesn't get called?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I have it clear in my head about which case you're asking for.

This case is covering three calls, at 10s, 13s, and 16s. We're verifying that NotifyIdle only gets called twice: the very first call and the last one.

std::make_unique<MockRuntimeController>(client, task_runners_);

EXPECT_CALL(*mock_runtime_controller, NotifyIdle(200, 100)).Times(1);
EXPECT_CALL(*mock_runtime_controller, NotifyIdle(400, 0)).Times(1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this line here is verifying that we didn't get called (the second param is 0) at the 13s mark.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yea, a bit weird to follow since mocking and calling are in different spaces and it isn't straitforward. You might want to add a comment like:
Here we assert NotifyIdle is called with the zero hint since we haven't advanced 5 (or name of timeout constant) seconds yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that - unfortunately it's this way because we std::move the pointer after this, and I didn't want to grab out a copy of the unique_ptr.

@dnfield
Copy link
Contributor Author

dnfield commented May 3, 2021

I've filed flutter/flutter#81514, since that would be an even better fix. If we could really do that, we should be able to drop the whole images notify the VM to maybe do a GC to clean themselves up.

@DizzyDuan
Copy link

https://github.com/flutter/flutter/issues/80702

I hope it can be merged as soon as possible, which brings us great distress and brings bad experience to users.

@dnfield @chinmaygarde @zanderso

@dnfield dnfield deleted the img_gc branch June 22, 2021 15:39
@dnfield
Copy link
Contributor Author

dnfield commented Jun 22, 2021

@DizzyYang this patch has been merged, and it has rolled into the framework.

I'm working on an additional follow up that will do a better job in this case, see flutter/flutter#84740

I'm not aware of any plans to CP these fixes into stable though, if that's what you're looking for.

@DizzyDuan
Copy link

DizzyDuan commented Jun 23, 2021

@dnfield Thank you for your reply.

[✓] Flutter (Channel stable, 2.2.2, on macOS 11.4 20F71 darwin-x64, locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] Connected device (3 available)

This is the version of SDK we are using. In this version, the CPU still has a big problem.

This version should not be merged yet, and I hope it can be merged as soon as possible.

@dnfield
Copy link
Contributor Author

dnfield commented Jun 23, 2021

No.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Performance] Gif will make GC frequently, and it'll make the phone heat up
5 participants