这里可以找到示例代码 https://github.com/PVoLan/TestActivityDispose
我们有两项活动。一个按钮导致第二个活动。第二个活动有30个TextView(模拟复杂的UI)和后退按钮。
向前和向后切换活动会导致GREF数量快速增长。它需要大约60次点击前进和后退溢出2k限制和崩溃应用程序。
可以在存储库中找到Android日志。从日志中可以看出,由于TextViews(1543 GREF),GREF溢出最多。另一个GREFS是:
因此,正如我们所看到的,活动完成时不会释放活动资源(尽管调用了OnDestroy) 我怎样才能正确释放所有这些GREF?
答案 0 :(得分:1)
问题是这个过程中有两个GC(Dalvik& Mono),并且都不知道对方使用了多少内存。例如,所有Mono看到的TextView
个实例都是一个非常小的对象(主要是IntPtr
和来自Java.Lang.Object
的其他支持字段):
namespace Java.Lang {
public class Object {
IntPtr handle;
// ...
}
}
namespace Android.Widget {
public class TextView : Java.Lang.Object {
// ...
}
}
也就是说,对于大多数绑定类型,没有后果的数据成员,并且C#包装器非常小。 Mono不知道 - 也不知道 - 有一个与Object.handle
相关联的Java对象,以及(更重要的是)该对象引用了多少内存。
因此,您偶尔需要帮助它:
// https://github.com/PVoLan/TestActivityDispose/blob/master/Test/Activity2.cs
public class Activity2 {
// ...
protected override void OnDestroy ()
{
Android.Util.Log.Info("----------", "Destroy");
base.OnDestroy ();
GC.Collect ();
}
}
添加的GC.Collect()
调用将为Mono的GC提供执行和收集垃圾对象的机会。添加该行后,反复点击“Hello World,Click Me!”和“返回”等级为93-126 grefs(取决于您正在进行的活动)。