【问题标题】:I want to know why FinalizerReference consume so much memory in my application我想知道为什么 FinalizerReference 在我的应用程序中消耗这么多内存
【发布时间】:2019-02-07 15:22:49
【问题描述】:

我的应用程序无法在 android 4.x 上运行,所以我只是在分析我的应用程序的堆数据,我发现 java.lang.FinalizerReference 保留了这么多内存。任何人都可以解释一下吗?任何想法将不胜感激。

【问题讨论】:

  • 为每个具有“非平凡”finalize() 方法的对象创建一个FinalizerReference。您可以检查FinalizerReference 实例的引用以找出负责的对象(以及相应的类)。然后,您可能会重新考虑它是否真的需要自定义 finalize() 方法。
  • @Holger 是的,我查过了,都是框架的类,比如android.os.Parcel,我自己定义的类没有覆盖finalize()方法。
  • 那么,没有什么可以改变的了。但请注意,FinalizerReference 实例不会消耗那么多内存 (48kB); “保留大小”包括所指对象的内存以及可能通过该对象可访问的更多对象。当这些对象只能通过这些引用对象访问时,这表明后续的垃圾收集/终结循环可以删除它们。
  • 我观察了我的应用程序 30 分钟,FinalizerReference 保留的内存在增加,并且没有减少。⊙﹏⊙‖∣
  • 好吧,一个应用程序可以运行 30 分钟甚至几天而无需任何垃圾收集。这可能违反直觉,但分配的内存不会受到伤害,只要它实际上不需要用于其他目的。所以他们的问题是,这些对象是否继续使用内存,当你这样做时,强制垃圾收集或让内存完全运行。

标签: java android memory-management heap-memory


【解决方案1】:

确实没有。

我也遇到了这个问题,我创建了a separate question 并在找到你之前回答。我想我真的找到了它的根源。

tldr:在分析时像对待任何其他类一样对待 FinalizerReference(正如 Memory Profiler 所做的那样),会导致在计算 Retained Size 时重复计算相同的内存。因此,目前您可以(几乎总是)将 Memory Profiler 报告的 FinalizerReference 类的 Retained Size 视为毫无意义。

正如Holger 在 cmets 中指出的那样,通常只有类的 48 kB 浅大小(在您的情况下)很重要。然而,报告的大约 63 MB 的保留大小甚至不包括引用对象的内存,只包括递归计数的其他 FinalizerReference 实例。 (unconvinced? read more)

但是那些指示物真的很重要,尤其是那些只是在被垃圾收集之前等待被 finalize() 处理的对象。因此,正如 Holger 所假设的,Memory Profiler应该显示它们,因为它们中的大量表明一个迫在眉睫的问题。

我认为这是 Android Studio 的内存分析器中的一个错误,并已提交this issue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多