Flutter“计算”内存泄漏-如何停用计算实例使用的堆变量?

pua*_*rgs 5 dart flutter

在将一堆下载的JSON反序列化为对象时,我试图在移动应用程序中使用计算实例来减少麻烦

当我使用实施反序列化方法计算,堆一直在通过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.");
  }

Run Code Online (Sandbox Code Playgroud)

在上面的代码中,相关行以“ currentEvents =”开头。正常的内存行为可以通过以下方式看到:

  currentEvents = EventModel.fromJsonArray(json);
Run Code Online (Sandbox Code Playgroud)

使用以下命令可以看到失控的内存行为:

  currentEvents = await compute(EventModel.fromJsonArray, json);
Run Code Online (Sandbox Code Playgroud)

请注意,变更EventModel.fromJsonArray到一个异步方法具有NO上的任何上述仿形的影响。将其更改为异步也不会导致垃圾邮件消失。我已经考虑过了。我可以在代码中添加人为延迟,以便在映射方法中引入异步拆分,但这不是我要在此处执行的操作-我需要尽快返回数据,这就是为什么使用compute是理想的选择。

即使在“流关闭中”被打印,流被关闭,父对象从层次结构中退出并收集之后,与计算方法关联的任何内存也永远不会退出。

如何获得计算实例以适当地收回内存?我在这里做错什么了吗?

Fra*_*ažo 1

我在 flutter 2.2.3 上看到同样的问题

data我作为参数传递给计算的所有内容都保存在内存中 - await compute(exampleGlobalFunction, data)

我在Flutter DevTools/Memory选项卡中检查了它,并且数据实例从未被释放。如果我直接调用该函数(无需计算),那么数据将被正确释放。

编辑:我想我找到了解决方案 - 创建了一个 github 问题https://github.com/flutter/flutter/issues/86470