Skip to content

Conversation

@polina-c
Copy link
Contributor

@polina-c polina-c commented Aug 25, 2022

Design: go/dart-leaktracker-productization
Peer PR in engine: flutter/engine#35274

Verified memory_allocations.dart is not included into release build if the flag --dart-define=flutter.memory_allocations=true is not passed:

Screen Shot 2022-09-01 at 9 22 14 PM

@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label Aug 25, 2022
Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

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

I'm not quite clear on how this will be used or why it belongs in the framework at this point.

@polina-c polina-c changed the title Create class MemoryAllocation. Create class MemoryAllocations. Aug 25, 2022
Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

It's kinda difficult reviewing this skeleton without docs filled in and seeing how this would be used by other parts of the framework.

@polina-c polina-c marked this pull request as ready for review September 1, 2022 03:51
object: this,
));
}
_creationDispatched = true;
Copy link
Member

Choose a reason for hiding this comment

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

Why is the inherited implementation from ChangeNotifier not enough? Also, it is odd that this is reaching out to a private in ChangeNotifier. Does that mean, I couldn't implement my own ValueNotifier-like class based on ChangeNotifier outside of the framework?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the implementation is not super-elegant. However, as there is no constructor in ChangeNotifier (because it is used as mixin), I did not find a better way.

You can implement ValueNotifier-like class based on ChangeNotifier though. It will dispatch the events if only a listener is added.

@override
void addListener(VoidCallback listener) {
assert(ChangeNotifier.debugAssertNotDisposed(this));
if (!_creationDispatched) {
Copy link
Member

Choose a reason for hiding this comment

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

One thought that occurred to me: In release builds that ship to customers you probably want this entire code tree-shaken out. That's currently no possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for bringing it. Introduced kFlutterMemoryAllocationsEnabled and verified tree-shaking happens (see screen shot in description)

assert(ChangeNotifier.debugAssertNotDisposed(this));
if (!_creationDispatched) {
if (MemoryAllocations.instance.hasListeners) {
MemoryAllocations.instance.dispatchObjectEvent(ObjectCreated(
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure how these events will be consumed, but will it not be confusing if an object creation notification is received somewhat randomly long after the object has been created?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is not perfect, but I do not see other way to inform about ChangeNotifier creation.


/// List of the Flutter Framework and SDK libraries with instrumented
/// classes.
class FlutterLibraries {
Copy link
Member

Choose a reason for hiding this comment

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

Does this have to be public API?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reomoved

try {
listeners[i]?.call(objectEvent);
} catch (exception, stack) {
final String type = objectEvent.object.runtimeType.toString();
Copy link
Member

Choose a reason for hiding this comment

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

There should be a no_runtimeType_toString lint on this line, no?

Copy link
Contributor Author

@polina-c polina-c Sep 1, 2022

Choose a reason for hiding this comment

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

nope

And if i remove the type, I get lint about return type

return;
}

if (_activeDispatchLoops > 0) {
Copy link
Member

Choose a reason for hiding this comment

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

For my own understanding, why is the removal/notification logic so different from ChangeNotifier? I wish we could just reuse that logic instead of reinventing everything.

Copy link
Contributor Author

@polina-c polina-c Sep 1, 2022

Choose a reason for hiding this comment

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

ChangeNotifier is different, because it is not-singletone and is optimized for often adding/removing listeners.
One of comments in ChangeNotifier is 'The list holding the listeners is not growable for performances reasons.'.
We are ok with growable list for MemoryAllocations, because it is singletone.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We still care about performance for event dispatching, as the number of events can be huge.

@polina-c polina-c marked this pull request as ready for review September 9, 2022 18:48
Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

LGTM

@polina-c polina-c merged commit a3c3dc8 into flutter:master Sep 10, 2022
@polina-c polina-c deleted the ma branch September 10, 2022 00:23
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 10, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 10, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 10, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 11, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 12, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 12, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 12, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Sep 13, 2022
@polina-c
Copy link
Contributor Author

Following up.

@polina-c
Copy link
Contributor Author

polina-c commented Sep 13, 2022

@dnfield
Copy link
Contributor

dnfield commented Sep 14, 2022

From offline conversation:

  • Polina got initial results from an emulator, which may be why the differences didn't show up.
  • We should probably just turn this off by default in profile mode and enable it on benchmarks/tests/situations that need it explicitly.
  • The benchmarks this affected are change notifier related ones, which are likely to be somewhat impactful in real life apps using Provider, so this may affect internal benchmarks.

@polina-c is going to follow up with a patch to remove the || kProfileMode for now.

@polina-c
Copy link
Contributor Author

fix: #111615

@polina-c
Copy link
Contributor Author

polina-c commented Sep 15, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants