【问题标题】:Background concurrent copying GC freed - Flutter后台并发复制 GC 释放 - Flutter
【发布时间】:2019-01-09 19:49:07
【问题描述】:

在我的 Flutter 日志中,我不断收到这些消息(只是数字不同):

Background concurrent copying GC freed 153040(3MB) AllocSpace objects, 12(4MB) LOS objects, 49% free, 4MB/8MB, paused 819us total 173.633ms

我最近实现了 bloc 模式,我对流不太熟悉,也许我在那里做错了什么......

我有大约 5000 行代码,所以我不能在这里全部发布,只是想知道你是否知道这个问题,也许这是一个常见的错误。

编辑:哦,是的,顺便说一句,我正在 Android Emulator,Android Pie 上进行测试。我的平台是 Windows。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    这不是错误,它只是一条 Android 日志消息,通知您何时进行垃圾收集。 一切正常。 日志消息不会损害您的应用程序,请参阅this question regarding the same topic on native Android。 如果您的内存不足,或者您看到由于垃圾收集而导致的性能问题,这只是一个问题。 唷。


    话虽如此,让我们看看如何减少这些消息。

    • 通常,模拟器的资源是有限的。 因此,最简单的方法是增加模拟器的 RAM 大小或使用实际手机而不是模拟器。

    • 其次,确保您的逻辑不会处理大量数据,或者如果可以,尽快处理。

    • 另外,不要自己“缓存”小部件,将它们存储在如下状态:

      class _MyWidgetState extends State<MyWidget> {
        Widget button;
      
        @override
        void initState() {
          super.initState();
          button = RaisedButton(...);
        }
      
        @override
        Widget build() => button;
      }
      

      要了解有关为什么不这样做的更多信息,请查看my answer to a somewhat related question。 基本上,Dart 使用两种类型的垃圾收集器,Young Space Scavenger 用于短期对象,Mark Sweep GC 用于长期对象。 通过手动缓存您的小部件,您依赖于后者,后者速度较慢,并且实际上可能会通知 Android 已释放的内存,从而导致您的日志。

    • 最后,您可以随时过滤或忽略日志。 :D

    【讨论】:

    • 感谢您的回答,但我认为问题不在于模拟器上的内存限制......我最近从使用 setState() 的非常昂贵的业务逻辑切换到 Bloc 模式,现在我的应用加载速度明显变慢,同时只处理少量数据...
    • 诚然,这听起来不太好。我怀疑你的一些小部件或巨大的子树经常不必要地重建。检查小部件何时重建并将.distinct() 添加到传出的 BLoC 流中,过滤掉连续多次发送的相同值。另外,我推荐诊断性能问题的标准程序:flutter.io/docs/testing/ui-performance
    • 谢谢,我明天试试。如果它有助于解决我的问题,我会将您的答案标记为正确。
    • 我不知道我在哪里犯了这个错误。你能帮我解决这个问题吗?
    • 您可以使用 Dart DevTools 来调试创建了哪些对象并监控内存使用情况。这是一个介绍:dart.dev/tools/dart-devtools
    【解决方案2】:

    显然这是我自己犯的一个愚蠢的错误......我做了一些更新功能,向Stream 添加了一些内容,然后立即再次被调用,因为它也在监听Stream。所以有一个无限循环添加和响应Stream

    感谢任何人的帮助,有一些有用的提示!

    【讨论】:

    • 我不知道我在哪里犯了这个错误。你能帮我解决这个问题吗?
    【解决方案3】:

    这意味着您的应用正在使用内存并且它正在被 GC(垃圾收集器)释放。如果内存要求不是太高,您不会看到 GC 启动很多时间来释放内存,但如果它使用太多内存,那么您的应用程序将滞后。如果性能受到影响,那么您需要修复它。如果可以的话,在真机上测试一下。

    【讨论】:

    • 我不知道我在哪里犯了这个错误。你能帮我解决这个问题吗?
    【解决方案4】:

    这应该是正常的,直到您的消息显示 0% Free 并且 GC 释放的数量很低。这意味着您的内存不足,需要重新设计您的代码。

    Background concurrent copying GC freed 3(64B) AllocSpace objects, 0(0B) LOS objects, 0% free, 191MB/192MB, paused 217us total 1.338s
    

    【讨论】:

      【解决方案5】:

      并不是要提出这个问题/答案,但万一现在对其他人有用......出现此消息的另一个原因是当应用程序的逻辑进入无限循环时(例如,光标永远不会移动到下一个记录等)。最终,GC 开始在这种情况下做太多的工作。

      【讨论】:

        【解决方案6】:

        老问题和一些很好的答案,但就我而言,我忘记在数据库查询中包含 cursor.moveToNext(),所以我在创建时运行了一个无限循环无限数量的对象——以防万一它对任何人有用。

        【讨论】:

          猜你喜欢
          • 2021-12-15
          • 1970-01-01
          • 2017-07-11
          • 1970-01-01
          • 1970-01-01
          • 2016-07-30
          • 1970-01-01
          • 2017-02-12
          • 1970-01-01
          相关资源
          最近更新 更多