本文介绍了Monodroid GREF 问题最佳实践?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下测试代码(基于标准的 monodroid HelloWorld)

I have the following test code (based on standard monodroid HelloWorld)

namespace TestGREF
{
    [Activity (Label = "TestGREF", MainLauncher = true)]
    public class Activity1 : Activity
    {
        int count = 1;
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);
            SetContentView (Resource.Layout.Main);
            Button button = FindViewById<Button> (Resource.Id.myButton);

            button.Click += delegate {
                button.Text = string.Format ("{0} clicks!", count++);
                for(int i=0;i<10000;i++){
                    new Java.Lang.Object(new System.IntPtr(i));
                    //...some stuff here. Instead of Java.Lang.Object may be
                    //something much more useful.
                }

                //If uncomment here, looks ok
                //GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            };
        }
    }
}

如果我点击按钮 5-6 次,应用程序就会崩溃.

If I click the button 5-6 times, application crashes.

我知道这是因为全局引用 (GREF) 限制(在此处描述,意外NullReferenceExceptions"部分).问题是:用它做什么?最佳做法是什么?如果可能,请提供代码示例

I know this happens because of global refences (GREF) limit (described here, "Unexpected NullReferenceExceptions" section). The question is: what to do with it? What is the best practice? If possible, with code example please

如果取消注释 GC.Collect() 调用,似乎一切正常,但过于频繁地调用 GC 对性能来说太昂贵了.另一种流行的设计是将新语句放入循环中,但这并不总是程序逻辑的可能原因.

If uncomment GC.Collect() call, all seems working, but calling GC too often is too exspensive for performance. Another popular design is to put new statement put of loop, but it is not always possible cause of program logic.

还有什么想法吗?

推荐答案

for(int i=0;i<10000;i++){
    var obj = new Java.Lang.Object(new System.IntPtr(i));

    //...some stuff here. Instead of Java.Lang.Object may be
    //something much more useful.

    obj.Dispose(); //Deletes an object and GREF too.
    //Cannot be used if object is still used in dalvik VM
}

如果您不能使用 Dispose()(例如,非托管对象是布局的一部分,它将被 android lated 使用,但不会被 C# 代码使用),请明智地使用 GC.Collect().GC.Collect() 删除变量的所有 GREF,这些变量不在 Mono 环境中使用且超出当前范围.

If you cannot use Dispose() (for example, unmanaged object is a part of layout, which will be used by android lated, but not by C# code), use GC.Collect() wisely. GC.Collect() kills all the GREFs to variables, which are out of usage by Mono Environment and out of current scope.

这篇关于Monodroid GREF 问题最佳实践?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 02:31