【问题标题】:Xamarin Android Memory - Strict Mode instances=2; limit=1Xamarin Android 内存 - 严格模式实例 = 2;限制=1
【发布时间】:2017-02-16 18:41:34
【问题描述】:

我已经查看了有关此主题的其他一些帖子,但还没有找到我正在寻找的答案。我正在尝试评估一些 Xamarin Android 应用程序中的内存使用情况,并且对这个主题感到相当困惑。

为了我自己的利益,我正在使用最基本的应用程序进行此初始测试。有两个活动。第一个活动有一个启动第二个活动的按钮。然后我单击硬件返回按钮,然后返回第一个活动。我将发布代码,但仅此而已。

我已添加:

        var builder = new StrictMode.VmPolicy.Builder();
        var policy = builder.DetectActivityLeaks().PenaltyLog().Build();
        StrictMode.SetVmPolicy(policy);

在我的两个活动的 OnCreate 内部,尝试查看任何违规行为或活动是否泄漏。我观察到的是加班,我从第二个活动中单击后退按钮,我得到一个控制台输出

[StrictMode] 类 md5774612d1059550a86887b889cb974a69.SecondActivity;实例=2;限制=1 [StrictMode] android.os.StrictMode$InstanceCountViolation: 类 md5774612d1059550a86887b889cb974a69.SecondActivity;实例=2;限制=1 [StrictMode] 在 android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)

每次我加载下一个活动并再次点击后退按钮时,这将继续增加“实例”。我不明白为什么存在多个实例。仅仅是因为垃圾收集器没有花时间清理之前的活动吗?或者即使在这个简单的应用程序中,我真的有活动的内存泄漏?如果我在屏幕的 onResume 中调用 System.GC.Collect(),我不再看到多实例违规。显然我不想告诉垃圾收集器什么时候做它的工作,所以如果问题只是它还没有解决它,我认为没关系?但是我应该遵循什么更好的做法来确保我的活动释放所有内存?谢谢你的建议。

以下两个活动的代码。

using Android.App;
using Android.Widget;
using Android.OS;
using Android.Content;

namespace Test.Droid
{
[Activity (Label = "Test.Droid", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : Activity
{
    int count = 1;

    protected override void OnCreate (Bundle savedInstanceState)
    {
        base.OnCreate (savedInstanceState);

        var builder = new StrictMode.VmPolicy.Builder();
        var policy = builder.DetectActivityLeaks().PenaltyLog().Build();
        StrictMode.SetVmPolicy(policy);
        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        Button button = FindViewById<Button> (Resource.Id.myButton);

        button.Click += delegate {
            Intent intent = new Intent(this, typeof(SecondActivity));
            StartActivity(intent);
        };
    }

    protected override void OnResume()
    {
        base.OnResume();
        //System.GC.Collect();
    }
}
}

第二个活动

using System;
using Android.App;
using Android.Widget;
using Android.OS;
namespace Test.Droid
{
[Activity(Label = "Test.Droid")]
public class SecondActivity : Activity
{
    int count = 1;

    public SecondActivity()
    {

    }

    protected override void OnCreate(Bundle savedInstanceState)
    {

        base.OnCreate(savedInstanceState);

        var builder = new StrictMode.VmPolicy.Builder();
        var policy = builder.DetectActivityLeaks().PenaltyLog().Build();
        StrictMode.SetVmPolicy(policy);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        Button button = FindViewById<Button>(Resource.Id.myButton);

        button.Click += delegate
        {
            button.Text = string.Format("{0} clicks!", count++);
        };      }

}
}

【问题讨论】:

    标签: android xamarin memory-leaks garbage-collection xamarin.android


    【解决方案1】:

    您可以在开发者选项中设置不保留活动,强制ART/Dalvik尽快清理活动进行测试。

    就个人而言,我在很多地方都使用GC.Collect 来强制 Mono(以及因此 ART/Dalvik)清除内存。其中大多数与遍历 Java/C# 桥的图像/位图有关,最终您会得到一个在两个 VM 中都“存在”的位图,因此会消耗双倍的内存...

    参考:https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多