blob: d88677f5bdec9e956f0f08d247309a0c936b8ea1 [file] [log] [blame] [view] [edit]
There are many ways to write a memory test for Flutter. In this article, we give 3 classes of example tests that are currently used by Flutter device lab. Memory performance is a high priority for Flutter so there are many new memory tools and test utilities in progress. Well add them in this doc in the future.
## [MemoryTest][class MemoryTest] that interacts with adb directly
These memory tests use the [MemoryTest class defined in the device lab perf_tests.dart][class MemoryTest] to poll adb directly before and after an overridable `useMemory` function. By default, `useMemory` will just run an app in release and wait for a done message to be printed in logcat.
Examples include
- [`complex_layout_scroll_perf__memory`][complex layout memory manifest]
- [device lab task file][complex layout memory task]
- [main file][complex layout memory main]
- [`fast_scroll_large_images_memory`][fast scroll memory manifest]
- [device lab task file][fast scroll memory task]
- [main file][fast scroll memory main]
To write a new MemoryTest case `some_memory_perf` and add it to Flutters device lab so Flutters CI system can measure it for each Flutter commit, follow examples above to
1. Create a `main` function for the test app in a file named like `test_memory/some_memory_perf.dart`.
2. Add a `some_memory_perf` entry to [manifest.yaml][manifest]
3. Add a `some_memory_perf.dart` file to [dev/devicelab/bin/tasks][tasks] folder.
### Pros
- Low overhead.
- Works in all runtime modes, including release.
- The test has complete control on when to start and stop the memory measurement.
### Cons
- Only have 2 memory readings, begin and end, during the app run.
- Polling ADB may trigger collections of the Java heap.
- Only works on Android targets.
- Requires a test environment with access to ADB.
- Requires a host machine with Flutter SDK installed.
## DevTools Memory Test
The memory tests use DevTools to poll adb and Dart VM during a normal Flutter driver test run, which typically measures speed performance instead of memory performance. [DevToolsMemoryTest][class DevToolsMemoryTest] handles most of the process so a new test only needs to specify the driver test location.
Examples include
- [`complex_layout_scroll_perf__devtools_memory`][complex layout devtools memory manifest]
- [device lab task file][complex layout devtools memory task]
- [`large_image_changer_perf_android`][large image changer manifest]
- [device lab task file][large image changer task]
To write a new DevTools memory test case `some_memory_perf` and add it to Flutters device lab so Flutters CI system can measure it for each Flutter commit, follow examples above to
1. Write (or reuse) a normal Flutter driver test for the app in files named like `test_driver/some_memory_perf.dart` and `test_driver/some_memory_perf_test.dart`.
2. Add a `some_memory_perf` entry to [manifest.yaml][manifest]
3. Add a `some_memory_perf.dart` file to [dev/devicelab/bin/tasks][tasks] folder.
### Pros
- Have finer grained measurements (~1 reading per second).
- Also have Dart VM memory info.
- Can easily turn a speed-focused driver test into a memory test.
### Cons
- Dont have much control on when to start and stop the measurement.
- Polling ADB may trigger collections on the Java heap.
- Requires a test environment with access to ADB.
- Only works on Android targets.
- Not available for release mode, so may incur extra memory overhead in profile or debug mode.
- Requires a host machine with Flutter SDK installed.
## iOS Memory Test
The iOS embedding of Flutter supports sampling memory usage during runtime, which then writes metrics to the [Dart timeline][Dart timeline]. After recording a timeline for the relevant portion of an applications execution, the timeline can be analyzed to obtain memory related information from the profile.
Examples include
- [`large_image_changer_perf_ios`][large image changer manifest ios]
- [device lab task file][large image changer task ios]
To write a new iOS memory test case `some_memory_perf` and add it to Flutters device lab so Flutters CI system can measure it for each Flutter commit, follow examples above to
1. Write (or reuse) a normal Flutter driver test for the app in files named like `test_driver/some_memory_perf.dart` and `test_driver/some_memory_perf_test.dart`.
2. Add a `some_memory_perf` entry to [manifest.yaml][manifest]
3. Add a `some_memory_perf.dart` file to [dev/devicelab/bin/tasks][tasks] folder that specifies `measureMemory: true`.
### Pros
- Can be run on a machine that does not have the Flutter SDK installed.
- Can adjust the sampling frequency so one can have as many or as few measurements as needed.
- Each sampling has much less overhead compared to calling adb
- Flutter driver tests on iOS get memory measurements for free.
### Cons
- Only works on iOS targets.
- Not available for release mode, so may incur extra memory overhead in profile or debug mode.
- Memory polling mechanism may incur additional memory overhead.
[manifest]: https://github.com/flutter/flutter/blob/main/dev/devicelab/manifest.yaml
[tasks]: https://github.com/flutter/flutter/tree/main/dev/devicelab/bin/tasks
[class MemoryTest]: https://github.com/flutter/flutter/blob/51bb11f7cece47840a9ee6d6d43db97ab16b31df/dev/devicelab/lib/tasks/perf_tests.dart#L941
[complex layout memory manifest]: https://github.com/flutter/flutter/blob/7e41425d4af21dec7a7ff072a3ec1387859e32c8/dev/devicelab/manifest.yaml#L329
[complex layout memory task]: https://github.com/flutter/flutter/blob/main/dev/devicelab/bin/tasks/complex_layout_scroll_perf__memory.dart
[complex layout memory main]: https://github.com/flutter/flutter/blob/main/dev/benchmarks/complex_layout/test_memory/scroll_perf.dart
[fast scroll memory manifest]: https://github.com/flutter/flutter/blob/7e41425d4af21dec7a7ff072a3ec1387859e32c8/dev/devicelab/manifest.yaml#L837
[fast scroll memory task]: https://github.com/flutter/flutter/blob/main/dev/devicelab/bin/tasks/fast_scroll_large_images__memory.dart
[fast scroll memory main]: https://github.com/flutter/flutter/blob/main/dev/benchmarks/macrobenchmarks/test_memory/large_images.dart
[class DevToolsMemoryTest]: https://github.com/flutter/flutter/blob/7e41425d4af21dec7a7ff072a3ec1387859e32c8/dev/devicelab/lib/tasks/perf_tests.dart#L1138
[complex layout devtools memory manifest]: https://github.com/flutter/flutter/blob/7e41425d4af21dec7a7ff072a3ec1387859e32c8/dev/devicelab/manifest.yaml#L359
[complex layout devtools memory task]: https://github.com/flutter/flutter/blob/main/dev/devicelab/bin/tasks/complex_layout_scroll_perf__devtools_memory.dart
[large image changer manifest]: https://github.com/flutter/flutter/blob/7e41425d4af21dec7a7ff072a3ec1387859e32c8/dev/devicelab/manifest.yaml#L874
[large image changer task]: https://github.com/flutter/flutter/blob/main/dev/devicelab/bin/tasks/large_image_changer_perf_android.dart
[Dart timeline]:https://flutter.dev/docs/development/tools/devtools/timeline
[large image changer manifest ios]: https://github.com/flutter/flutter/blob/7e41425d4af21dec7a7ff072a3ec1387859e32c8/dev/devicelab/manifest.yaml#L880
[large image changer task ios]: https://github.com/flutter/flutter/blob/main/dev/devicelab/bin/tasks/large_image_changer_perf_ios.dart