我在我的Mono for Android应用程序中发现内存泄漏问题。我相信我遵循了后面所述的所有最佳实践,但是在一个活动的贯穿次数一致且可重复的数量之后,我一直在收到OutOfMemoryError。适用于Android的Mono - OutOfMemoryError
在模拟器上使用ddms
我可以看到,我们的应用程序每次使用ViewFlipper
时都会消耗大约200个额外的“数据对象”和大约30kB的内存。我们也在消耗其他资源,但速度要低得多。
我使用ViewFlipper
有点不同寻常;它只是翻转在一个方向,并删除View
S作已经被证明:
while (flipper.ChildCount > 2)
{
flipper.RemoveViewAt(0);
}
我非常注意对我们所使用的任何View
小号任何引用的Dispose()
,作为described in this blog post。我用using
宗教所有UI组件(其在范围的结束时自动Dispose()
的对象):
using (TextView questionView = header.FindViewById<TextView>(Resource.Id.question))
{
questionView.Text = question.Text;
}
这似乎并不对内存泄漏产生任何影响。每当我加载Bitmap
s(通常PNG文件,大小小于20kB)时,我都会使用相同的模式,我经常这样做。
更新:我使用扩展方法装载位图:
public static Bitmap BitmapFromAsset(this Context context, String asset)
{
Bitmap bitmap;
using (Stream stream = context.Assets.Open(asset))
{
bitmap = BitmapFactory.DecodeStream(stream);
stream.Close();
}
return bitmap;
}
位图然后被用于这样的:
using (Bitmap b = this.BitmapFromAsset(path))
{
imageView.SetImageBitmap(b);
}
更新:作为Aranda的下面所暗示的,我使用委托,所以这是我的代码中的一种常见模式:
using (View button = FindViewById(Resource.Id.button))
{
button.Click += delegate
{
// do something
};
}
更改此设置,以便在删除View
时删除处理程序不会导致泄漏。
更新:Bug posted with Xamarin with example project。
是的,我使用委托来附加到不同的'视图'。所以我必须删除所有使用委托的事件处理程序,或一般的所有事件处理程序?假设你有这个:'使用(Button b = FindViewById
即使从等式中删除“Click”处理程序,我仍然以与上述相同的方式泄漏内存。 –
有趣。您的特定示例不会导致它泄漏,因为委托是一个匿名方法,并且将位于视图实例本身的范围内。我想我也没有很好地解释自己。由于我的GameScreen已将其中一种方法附加到我的Engine类中的事件(或委托)中,所以我的漏洞已经泄漏。引擎仍然通过附加事件持有对GameScreen类的引用。不一定与泄漏有关:( – Aranda