我注意到我的一项 Activity 中的内存异常增加。因此我进行了一些测试:我多次打开对话框(打开 - 关闭 - 打开 - 关闭......)并且内存不断增加。所以我使用 DDMS 转储 HPROF 文件并在 MAT 中打开它(内存分析器)。泄漏可疑报告表明,内存消耗增加的主要原因是:
所以我做了一个直方图,以检查我运行测试的那个对话框,以及是什么让它保持活跃。事实证明,它通过 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()
ingActivity
不会在引用时对其进行垃圾回收,如下所示: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 上,但不会发生在我的 Samsung Galaxy Mini GT-S5570 运行 Android 2.2.1。
IClipboardDataPasteEventImpl
对象最终会被释放,实际上,但只是在似乎不可预测的时候。
由于它们被 java.lang.ref.FinalizerReference
引用,我相信 IClipboardDataPasteEventImpl
对象正在等待 finalize()
'd,只有当 JVM 愿意时才会发生。有关详细信息,请查看这些 SO 问题:
解决方案/解决方法
抱歉,没有解决方案,但这是我最好的解决方法:
在 Activity
的 onDestroy()
中,尽可能多地释放对其他对象的引用(尤其是大对象,例如位图、集合和您 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 s2的textview
导致内存泄漏
leak是發生在android.widget.TextView$IClipboardDataPasteEventImpl這個interface上
泄漏 发生在 interface
android.widget.TextView$IClipboardDataPasteEventImpl
它會抓住mContext造成整個activity沒辦法被gc
它持有mContext
,阻止activity
被gc处理
同樣的程式在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 s2 的 ics 版本中得到解决...
关于android - 通过 IClipboardDataPasteEventImpl 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14135931/