You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Please upvote and comment on the issue if interested.
Why this is needed
Consider the common scenario: I have a ui.Image, a native audio player, or whatever heavy resource. Then, I want to ensure that, when the widget test is end (or even better, when the page is left in app), there are zero heavy resources there. This check can reveal bugs of the type "neither disposed nor GCed forever".
When will this happen in reality? Firstly, I have seen it in my app. Secondly, generally speaking, this can happen when users forget to call dispose + the object has a retaining path thus not GCed as well.
Will the proposed check cause false positives? I think it may be alleviated by using a whitelist.
Here, I simulated two scenarios, one using a widget, and another using direct allocation. (Indeed in the first scenario it may be GCed but I am not very sure.) I expect two tests to fail using the detector, but they both passed happily.
import'package:common_flutter_dev/src/leak_tracking.dart';
import'package:flutter/material.dart';
import'package:flutter_test/flutter_test.dart';
voidmain() {
group('simple play with leak tracker', () {
testWidgetsWithLeakTracking('StatefulWidget containing disposable objects', (tester) async {
await tester.pumpWidget(const_SimpleWidget());
});
testWidgetsWithLeakTracking('objects that live forever', (tester) async {
final controller =ScrollController()..addListener(_dummyListener);
_notGcedStorage.add(controller);
// _notGcedStorage.remove(controller); // comment it out to simulate leak
});
});
}
final _notGcedStorage =<Object>[];
class_SimpleWidgetextendsStatefulWidget {
const_SimpleWidget();
@overrideState<_SimpleWidget> createState() =>_SimpleWidgetState();
}
class_SimpleWidgetStateextendsState<_SimpleWidget> {
latefinalScrollController controller;
@overridevoidinitState() {
super.initState();
controller =ScrollController()..addListener(_dummyListener);
}
@overridevoiddispose() {
// controller.dispose(); // comment it out to simulate leaksuper.dispose();
}
@overrideWidgetbuild(BuildContext context) {
returnconstPlaceholder();
}
}
void_dummyListener() {}
Minimal implementation code
Here is a minimal implementation I used to detect non-disposed and non-gced ui.Image.
The text was updated successfully, but these errors were encountered:
fzyzcjy
changed the title
Is it possible to detect "neither disposed nor GCed forever"?
(Willing to PR) Is it possible to detect "neither disposed nor GCed forever"?
Jun 3, 2023
fzyzcjy
changed the title
(Willing to PR) Is it possible to detect "neither disposed nor GCed forever"?
Is it possible to detect "neither disposed nor GCed forever"?
Jun 3, 2023
Please upvote and comment on the issue if interested.
Why this is needed
Consider the common scenario: I have a
ui.Image
, a native audio player, or whatever heavy resource. Then, I want to ensure that, when the widget test is end (or even better, when the page is left in app), there are zero heavy resources there. This check can reveal bugs of the type "neither disposed nor GCed forever".When will this happen in reality? Firstly, I have seen it in my app. Secondly, generally speaking, this can happen when users forget to call
dispose
+ the object has a retaining path thus not GCed as well.Will the proposed check cause false positives? I think it may be alleviated by using a whitelist.
Proposal
A naive implementation may look like this:
In other words, if a object calls
dispatchObjectCreated
but neverdispatchObjectDisposed
, then warn it.For a minimal implementation, the code can be seen in the last section.
Reproduction sample
If I understand correctly how to use this package, here are reproduction sample. (You need to copy-paste the https://github.com/flutter/flutter/blob/60a87d079843fa1a3498d7f3263b076a23074221/packages/flutter/test/foundation/leak_tracking.dart file before using the following code.)
Here, I simulated two scenarios, one using a widget, and another using direct allocation. (Indeed in the first scenario it may be GCed but I am not very sure.) I expect two tests to fail using the detector, but they both passed happily.
Minimal implementation code
Here is a minimal implementation I used to detect non-disposed and non-gced ui.Image.
The text was updated successfully, but these errors were encountered: