我正在尝试使用 compute我的移动应用程序中的实例以减少 jank将一堆下载的 JSON 反序列化为对象时。
当我使用 compute 实现反序列化方法时,堆 both 传递的 JSON 和 返回的反序列化对象(在列表中)无限。 GC 正常触发,但不会从堆中删除对象,即使方法已关闭且父/调用对象已停用。因此,当使用 DevTools 内存分析器时,它会显示出失控的内存消耗 - 堆越来越大。
正常内存配置文件 - 直接调用反序列化方法时内存使用量徘徊在 45MB 左右(但会导致应用卡顿)
失控内存配置文件 - 内存使用量线性增加,并且在通过计算调用反序列化方法时永远不会退出(但不会导致应用程序卡顿)
static Stream<EventCommitInfoModel> getEventsAfterDate(DateTime date) async* {
// variable defs for scope reuse
while (count < maxCount && retryCount > 0) {
try {
json = await http.read(url);
// currentEvents = await compute(EventModel.fromJsonArray, json);
currentEvents = EventModel.fromJsonArray(json);
db = await AppStateModel.database;
await db.upsertEventModels(currentEvents);
yield new InfoModel(maxCount, currentEvents.length);
}
catch (ex) {
// try again or close
}
}
print("stream is closing.");
}
在上面的代码中,相关行以“currentEvents =”开头。正常的内存行为如下所示:
currentEvents = EventModel.fromJsonArray(json);
失控的内存行为表现为:
currentEvents = await compute(EventModel.fromJsonArray, json);
请注意,将 EventModel.fromJsonArray 更改为异步方法对上述任何分析没有影响。将其更改为异步也不会导致卡顿消失。我已经考虑过了。我可以在代码中添加人为延迟,以便在映射方法中引入异步拆分,但这不是我想要在这里做的 - 我需要数据尽快返回,这就是为什么使用计算是理想的。
即使在打印“流正在关闭”、流已关闭、父对象从层次结构中退出并收集之后,与计算方法关联的任何内存也永远不会退出。
如何让计算实例正确停用内存?我在这里做错了吗?
最佳答案
我在 flutter 2.2.3 上看到同样的问题
我作为参数传递给计算的所有 data
都保存在内存中 - await compute(exampleGlobalFunction, data)
。
我在 Flutter DevTools
/Memory
选项卡中检查了它,并且从未释放数据实例。如果我直接调用函数(不计算),那么数据就会被正确释放。
编辑:我想我找到了解决方案 - 创建了一个 github 问题 https://github.com/flutter/flutter/issues/86470
关于dart - Flutter 'Compute' 内存泄漏 - 如何停用计算实例使用的堆变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55695119/