我正在与内存问题作斗争,所以我想出了一个小测试应用程序,试图了解VM如何处理垃圾收集。 以下代码非常简单。
使用DDMS,我可以看到实例化的对象数量不断增加,并且从LinearLayout中删除的子节点永远不会被收集。 那是为什么?
namespace MemoryTests
{
[Activity(Label = "MemoryTests", MainLauncher = true, Icon = "@drawable/icon")]
public class Activity1 : Activity
{
private Timer _timer = new Timer();
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
_timer.Interval = 1000;
_timer.Elapsed += AddTextViews;
_timer.Start();
}
public void AddTextViews(object o, EventArgs args)
{
RunOnUiThread(() =>
{
var layout = FindViewById<LinearLayout>(Resource.Id.layout);
layout.RemoveAllViews();
for (int i = 0; i < 3000; i++)
{
TextView tx = new TextView(ApplicationContext);
layout.AddView(tx);
}
});
}
}
}
答案 0 :(得分:1)
好的,所以在这种特殊情况下代码的问题在于你没有在Invalidate()
上调用layout
。这意味着layout
,即使您已在其上调用RemoveAllViews()
,也不会重绘并仍然认为它之前有所有TextView
个实例。
因此,当您调用Invalidate()
时,它会使用新的TextView
实例重绘自身并忘记旧的实例。现在,只要没有别的东西可以引用它们,它们就可以被垃圾收集了。