由于AudioManager,Android Context Memory Leak ListView

Leo*_*Leo 21 android listview memory-leaks android-audiomanager

我有一个ListView,我希望在活动结束时从内存中清除它.但是,它似乎正在泄漏.当我检查了内存转储,并得到pathToGCListView我得到以下,

Class Name                                                          | Shallow Heap | Retained Heap 
android.widget.ExpandableListView @ 0x4063e560                      |          768 |        39,904 
|- list, mList com.hitpost.TeamChooser @ 0x405f92e8                 |          176 |         1,648 
|  '- mOuterContext android.app.ContextImpl @ 0x40657368            |          160 |           304 
|     '- mContext android.media.AudioManager @ 0x40662600           |           40 |           168 
|        '- this$0 android.media.AudioManager$1 @ 0x406626b0 Unknown|           24 |            24 
Run Code Online (Sandbox Code Playgroud)

我看到同样的情况泄漏了很多我的ListView's.诀窍是,我根本没有AudioManager在我的应用程序中使用任何地方,根本没有来自应用程序的声音.请帮忙,这让我发疯了.显然是想弄清楚为什么会发生这种情况以及可能是根本问题?

Hel*_*ang 8

与OP的泄漏无关,但是因为AudioManager导致泄漏而进入这里的人:

如果您因为使用VideoView而看到此泄漏,可能是因为此错误:https://code.google.com/p/android/issues/detail? id = 152173

如果正在加载视频,VideoView永远不会发布AudioManager.

如链接中所述,修复程序是使用ApplicationContext手动创建VideoView.

编辑:此工作将起作用,直到...如果视频解码器说视频有编码问题.VideoView尝试使用应用程序上下文弹出AlertDialog.比发生崩溃.

我能想到的唯一工作就是继续使用活动上下文创建视频视图,并在activity.onDestroy中,使用反射将AudioManager的mContext设置为应用程序上下文.

注意:必须使用activity.getSystemService(Context.AUDIO_SERVICE)而不是activity.getApplicationContext.getSystemService(Context.AUDIO_SERVICE)来获取AudioManager,因为AudioManager是Context的成员变量(如果从中获取它,您将得到错误的AudioManager实例应用上下文).

最后,您可能想知道为什么成员变量(AudioManager)阻止类(Activity)被垃圾回收.从内存分析器,它显示AudioManager由本机堆栈拥有.所以AudioManager不知何故没有正确清理自己.


zap*_*apl 5

AudioManager您的代码中有几个引用您没有主动创建.例如,每个可点击的View可能都有一个可以播放onClick声音[ 来源 ].我猜这就是链接.

AudioManager如果禁用"设置"中的单击声音,代码看起来不会创建引用.您可以尝试并检查是否仍有泄漏.

泄漏的原因可能是您View在ListView(适配器?)代码中持有某个对象.如果你把它们留在那里你可能有一个ViewAudioManager 参考,并保留Context参考)

  • 我不认为答案应该围绕Context.`AudioManager`是一个单例类和一个系统类.垃圾收集器知道这一点并相应地执行适当的收集.您需要做的就是在转储内存之前进行GC调用. (2认同)

小智 -4

如果您的应用程序因内存泄漏而崩溃,那么您可以使用 try - catch(java.lang.outofmemory) 来避免此崩溃。事实上,GC是由JVM本身调用的,因此程序员对此无法控制。您可以将应用程序安装在SD卡中,在这种情况下将使用SD卡内存。不会发生内存泄漏。

只要去你的清单文件,一定有版本号。版本名称,还必须有“安装位置”,设为“preferExternal”。