Android删除的视图不会被垃圾收集
我正在与内存问题作斗争,所以我设计了一个小的测试应用程序,试图了解虚拟机如何处理垃圾收集。 下面的代码非常简单Android删除的视图不会被垃圾收集,android,xamarin.android,Android,Xamarin.android,我正在与内存问题作斗争,所以我设计了一个小的测试应用程序,试图了解虚拟机如何处理垃圾收集。 下面的代码非常简单 该活动仅由一个线性布局组成 每隔一秒钟,计时器就会调用一个方法,该方法1)从LinearLayout中删除所有子项2)将3000个新文本视图添加到布局中 使用DDMS,我可以看到实例化的对象数量不断增加,并且从LinearLayout中删除的子对象永远不会被收集。 为什么呢 namespace MemoryTests { [Activity(Label = "MemoryTes
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);
}
});
}
}
}
名称空间内存测试
{
[活动(Label=“MemoryTests”,MainLauncher=true,Icon=“@drawable/Icon”)]
公共课堂活动1:活动
{
专用计时器_Timer=新计时器();
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
//从“主”布局资源设置视图
SetContentView(Resource.Layout.Main);
_计时器。间隔=1000;
_timer.appeased+=AddTextViews;
_timer.Start();
}
public void addTextView(对象o、事件args args)
{
RunOnUiThread(()=>
{
var layout=findviewbyd(Resource.Id.layout);
layout.removeallview();
对于(int i=0;i<3000;i++)
{
TextView tx=新的TextView(ApplicationContext);
布局。添加视图(tx);
}
});
}
}
}
好的,因此在这种特殊情况下,代码的问题是您没有在布局上调用Invalidate()
。这意味着,layout
,即使您在其上调用了RemoveAllViews()
,也没有重新绘制,仍然认为它包含以前的所有TextView
实例
因此,当您调用Invalidate()
时,它会使用新的TextView
实例重新绘制自身,并忘记关于旧实例的所有内容。现在,只要没有其他引用它们,它们就可以被垃圾收集。你永远不会调用布局上的Invalidate()
,试试看这是否有帮助。只要你不在其他地方引用TextView
实例,它们就应该被标记为垃圾收集并最终被收集。嘿,奇奇!我看到你也潜伏在Xamarin论坛顶部的StackOverflow中。Invalidate()成功了。谢谢再一次,回答得很好。对于未来的读者:如果视图有一个带有可绘制的背景集,那么调用background.SetCallback(null)以确保它将被收集是很重要的