android - 通过 IClipboardDataPasteEventImpl 内存泄漏

标签 android memory-leaks android-ui

我注意到我的一项 Activity 中的内存异常增加。因此我进行了一些测试:我多次打开对话框(打开 - 关闭 - 打开 - 关闭......)并且内存不断增加。所以我使用 DDMS 转储 HPROF 文件并在 MAT 中打开它(内存分析器)。泄漏可疑报告表明,内存消耗增加的主要原因是:

enter image description here

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

最佳答案

调查

这是我的研究结果:

  • 它发生在内容 View 由 EditText 组成的任何 Activity 上。 finish()ing 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.4Samsung Galaxy Tab GT-P7300 上,但不会发生在我的 Samsung Galaxy Mini GT-S5570 运行 Android 2.2.1

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

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


解决方案/解决方法

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

ActivityonDestroy() 中,尽可能多地释放对其他对象的引用(尤其是大对象,例如位图、集合和您 Activity 的 subview ),像这样:

@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();
}

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

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


以下是我对 original blog entry 的翻译(中文)如问题中所述。希望这可以让大家更好地理解这个问题。

Galaxy S2 memory leak with TextView

不知道是不是哪邊弄錯

不知道哪里错了

但是galaxy s2的textview會產生memory leak

但是galaxy s2textview导致内存泄漏

leak是發生在android.widget.TextView$IClipboardDataPasteEventImpl這個interface上

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

它會抓住mContext造成整個activity沒辦法被gc

它持有mContext,阻止activitygc处理

同樣的程式在htc sensation(2.3.4)跟se xperia arc(2.3.4)和acer liquid(2.1)都沒有問題

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

而且網路上完全找不到android.widget.TextView$IClipboardDataPasteEventImpl相關的資料

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

android source code裡也找不到 看起來應該是samsung自己加的東西...

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

之前的opengl viewport bug 已經夠頭痛了 接下來soundpool相關bug也搞累很多人

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

現在這個memory leak又來攪局...

现在,内存泄漏来了……

看來手機外型還是比較重要 /_\... 外型好先吸到人來買 bug再慢慢修就好

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


[後記]

[附言]

經過一些試驗發現 只要按HOME button回到桌面,那些leak就會被釋放掉...

经过一些测试,我发现按HOME 键 返回桌面可以解决漏洞...

logcat會顯示一行Hide Clipboard dialog at Starting input: finished by someone else... !

它在 logcat 中显示 Hide Clipboard 对话框 Starting input: finished by someone... !

看起來galaxy s2裡面有偷偷對clipboard作一些操作...

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

但如果一直保持在app裡面運作的話,那些leak還是會存在...最後應該會發生OOM exception

但如果我们留在应用中,那些泄漏仍然存在......最终会发生OOM异常

現在只能期望galaxy s2 的ics版會修掉這個怪問題了...

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

关于android - 通过 IClipboardDataPasteEventImpl 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14135931/

相关文章:

javascript - IE11appendChild/removeChild内存泄漏

android - Android 版 WSS4J

iPhone 应用程序崩溃

c++ - VS2017 中的_crtBreakAlloc

android - 从 AsyncTaskLoader 更新 UI

android - 在 Android 5.0 中设置弹出菜单的样式

Android:使多行编辑文本可滚动,在垂直 ScrollView 中禁用

android - 我能知道 X dp 宽度的 TextView 可以容纳多少个字符吗?

java - 如何在 beanshell 中制作方法?

java - 如何仅从我的 Android 应用程序使用 Google Drive API 在 Google Drive 上创建和编辑电子表格文件?