Flutter中在ElevatedButton的onPressed或setState中实例化对象是否为不良实践?
Dart按钮点击重复实例化对象的内存疑问
初始场景与疑问
我之前在类中实例化了date01对象,但出现输入改变后结果却不变的问题。为解决该问题,我将AjtDateUtils类的对象实例化移至按钮的onPressed回调(准确说是setState内部),代码如下:
onPressed: () { setState(() { AjtDateUtils date01 = AjtDateUtils(); result = date01.function_call(firstController.text); }); }, child: const Text('Compute'))
现在我有几个疑问:
- 这种每次按钮点击时实例化对象的做法是否合理?
- 每次点击会导致内存占用持续递增吗?还是Dart会自动在下次实例化前销毁旧对象?
- 是否需要额外编写代码处理潜在问题?
测试过程与结果
为验证内存问题,我编写了如下测试代码:
import 'dart:io'; class SomeClass { var myList = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; } void main() { int response = -1; while (response != 0) { stdout.write("Input Integer: "); response = int.parse(stdin.readLineSync() ?? ""); for ( int i = 0 ; i < response ; i++ ) { SomeClass sc01 = SomeClass(); } } }
我通过Linux工具top记录内存数据:先记录初始内存读数,输入10000以实例化10000次对象,再记录Dart进程对应的VIRT、RES、SHR内存列数值,重复测试4次。
随后将循环内的代码修改为:
SomeClass? sc01 = SomeClass(); sc01 = null;
并重复4次相同测试,测试结果整理如下:
两种测试方式下,VIRT、RES、SHR的数值变化幅度极小,手动将对象设为null与不手动设置的内存占用差异不明显,多次测试后内存未出现持续递增的情况。
现在我想知道:
- 从这个测试结果能得出什么结论?
- 这个测试是否不够充分或高效?
内容的提问来源于stack exchange,提问作者rusty
相关产品推荐
相关产品推荐

