mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
122 lines
7.2 KiB
Markdown
122 lines
7.2 KiB
Markdown
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. We’ll 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 Flutter’s device lab so Flutter’s 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 Flutter’s device lab so Flutter’s 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
|
||
- Don’t 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 application’s 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 Flutter’s device lab so Flutter’s 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
|