2011-09-07 79 views
2

我在我的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

回答

1

我有一个类似的,很难找到问题(在WP7上的albiet,但它仍然是相关的,因为它都是.Net)。原来,我从另一个没有超出范围的类中将一些代表附加到我的GameScreen类中。确保你在做 - =任何附加的事件和委托,以及失去对视图实例的引用。

+0

是的,我使用委托来附加到不同的'视图'。所以我必须删除所有使用委托的事件处理程序,或一般的所有事件处理程序?假设你有这个:'使用(Button b = FindViewById

+0

即使从等式中删除“Click”处理程序,我仍然以与上述相同的方式泄漏内存。 –

+0

有趣。您的特定示例不会导致它泄漏,因为委托是一个匿名方法,并且将位于视图实例本身的范围内。我想我也没有很好地解释自己。由于我的GameScreen已将其中一种方法附加到我的Engine类中的事件(或委托)中,所以我的漏洞已经泄漏。引擎仍然通过附加事件持有对GameScreen类的引用。不一定与泄漏有关:( – Aranda