8

我注意到我的一项活动中出现了奇怪的记忆增加。因此我进行了一个小测试:我多次打开对话框(打开 - 关闭 - 打开 - 关闭 ....)并且内存不断增加。所以我使用 DDMS 转储一个 HPROF 文件并在MAT(内存分析器)中打开它。泄漏嫌疑报告指出,内存消耗增长的主要原因是:

在此处输入图像描述

所以我做了一个直方图,检查我运行测试的那个对话框,以及是什么让它保持活力。事实证明,它通过AutoCompleteTextViews保持活动状态,而 AutoCompleteTextViews 又通过android.widget.TextView$IClipboardDataPasteEventImpl 保持活动状态。但是,IClipboardDataPasteEventImpl 没有直接的支配者(当然,GC Root 除外)。我试图在互联网上找到 IClipboardDataPasteEventImpl 并搜索了 grepcode(android 源代码),但我唯一能想到的就是这个博客条目. 我看不懂那是什么语言,但我能读到的是英文单词,这表明它可能是三星 Galaxy SII 上的一个错误(我正在使用的手机,运行 android 2.3.x),与剪贴板管理器相关。但是我不确定这一点(我想解决这个问题,因此我不愿意简单地接受它是一个无法修复的错误)而且我不知道这个剪贴板是在哪里产生的以及为什么。我将非常感谢有关此事的任何指示/想法。

4

2 回答 2

8

调查

以下是我的研究结果:

  • 它发生在任何Activity内容视图包含EditText. finish()在引用Activity它时不会对其进行垃圾收集,如下所示:

    activity com.example.MyActivity
    <- mContext android.widget.TextView
        <- this$0 android.widget.TextView$IClipboardDataPasteEventImpl
            <- this$1 android.widget.TextView$IClipboardDataPasteEventImpl$1
                <- referent java.lang.ref.FinalizerReference
    
  • 它发生在运行Android 4.0.4的 Samsung Galaxy Tab GT-P7300上,但不会发生在运行Android 2.2.1的 Samsung Galaxy Mini GT-S5570上。

  • 实际上,这些IClipboardDataPasteEventImpl对象最终会被释放,但只是有时似乎是不可预测的。

由于它们被 引用java.lang.ref.FinalizerReference,我相信这些IClipboardDataPasteEventImpl对象正在等待被finalize()'d,这仅在 JVM 愿意时才会发生。有关详细信息,请查看以下 SO 问题:


解决方案/解决方法

抱歉,没有解决方案,但这是我最好的解决方法:

onDestroy()您的Activity中,尽可能多地释放对其他对象的引用(尤其是大对象,例如您的活动的位图、集合和子视图),如下所示:

@Override
protected void onDestroy()
{
    // Free reference to large objects.
    m_SomeLargeObject = null;
    m_AnotherLargeObject = null;

    // For ArrayList, if you are a paranoid to null, you may call clear() and then trimToSize().
    m_SomeLargeArrayList.clear();
    m_SomeLargeArrayList.trimToSize();

    // Free child views.
    m_MyButton = null;

    // Free adapters.
    m_ListViewAdapter = null;

    ... etc.

    // Don't forget to chain the call to the superclass.
    super.onDestroy();
}

IClipboardDataPasteEventImpl这样,我们至少可以减少伤亡,并希望在 JVM 有心情完成并收集所有这些邪恶的对象之前不会出现内存不足。

在垃圾收集环境的理想世界中,这是不必要的,但我想我们都应该意识到我们的世界并不完美,我们只能忍受这些缺陷。


以下是我对问题中提到的原始博客条目(中文)的翻译。希望这可以让大家更好地理解这个问题。

带有 TextView 的 Galaxy S2 内存泄漏

不知道是不是哪弄边错

不知道哪里出错了

但是galaxy s2的textview会产生内存泄漏

但是galaxy s2会导致textview内存泄漏

泄漏是发生在android.widget.TextView$IClipboardDataPasteEventImpl这个接口上</p>

泄漏发生在interface android.widget.TextView$IClipboardDataPasteEventImpl

它会抓住mContext造成整个活动没办法被gc

它持有mContext, 阻止activitygc 'ed

的程序在htc sense(2.3.4)跟se xperia arc(2.3.4)和acer liquid(2.1)都没有问题</p>

在htc sense(2.3.4)se xperia arc(2.3.4)acer liquid(2.1)上使用相同的应用程序没有这样的问题

网路上完全找不到android.widget.TextView$IClipboardDataPasteEventImpl相关的资料</p>

android.widget.TextView$IClipboardDataPasteEventImpl而且,我在网上根本找不到任何相关的东西

android源代码里也找不到看起来应该是三星自己加的东西...

甚至在android源代码中也没有,所以它似乎是三星自己添加的东西......

之前的opengl viewport bug 已经够头痛了

opengl viewport 的 bug已经很让人头疼了,soundpool相关的bug让很多人感到沮丧

现在这个内存泄漏又来困扰局...

现在,这里出现了内存泄漏问题......

看来手机外型还是比较重要的 /_\... 外型好先到人来买虫子再慢慢吸修就好了

看来手机的外观更重要/_\...好看的外观吸引顾客;错误可以稍后修复


[后记]

[PS]

一些试验立即按HOME按钮回到桌面,那些leak被释放掉...

经过一些测试,我发现可以通过按HOME 按钮返回桌面来释放泄漏...

logcat会显示一行在开始输入时隐藏剪贴板对话框:由其他人完成...!

它在开始输入时显示隐藏剪贴板对话框:由其他人完成...!在日志中

看起来 galaxy s2 里面有偷偷对剪贴板做一些操作...

似乎galaxy s2正在引擎盖下的剪贴板上运行......

但如果一直保持在应用程序里面准许的话,那些泄漏还是会存在……最后应该会发生OOM异常

但是如果我们留在应用程序中,这些泄漏仍然存在……最终会发生OOM 异常

现在只能修改galaxy s2的ics版会掉这个订婚怪问题了……

现在我们只能希望这个奇怪的问题能在galaxy s2的ics版本中得到解决……

于 2013-04-28T11:05:47.677 回答
7

我的 memleak 调查也把我带到了这里。我遇到了 Activity 在 EditText 上泄漏的问题。android.widget.TextView$IClipboardDataPasteEventImpl 对象持有持有活动的 EditText。这发生在三星 Galaxy Tab 10.1 和 Galaxy Tab 2 10.1、7.0 上。我无法在其他非三星设备(华硕、宏碁)上重现它。

不好的是我还没有找到解决方案:)

于 2013-02-12T13:52:56.530 回答