Monodroid - свободная память по окончании активности - PullRequest
0 голосов
/ 10 ноября 2011

Здесь можно найти пример кода https://github.com/PVoLan/TestActivityDispose

У нас есть два вида деятельности. У одного есть кнопка, ведущая ко второму виду деятельности. Второе действие имеет 30 TextViews (имитирующих сложный пользовательский интерфейс) и кнопку "Назад".

Переключение между действиями вперед и назад приводит к быстрому увеличению количества GREF. Требуется около 60 раз, чтобы перейти вперед и назад, чтобы переполнить 2k limit и вывести приложение из строя.

Журнал Android можно найти в хранилище. Как видно из журнала, переполнение GREF происходит чаще всего из-за TextViews (1543 GREF). Другие GREFS:

  • Кнопка (55 GREF) - кнопка BackB очевидно,
  • OnClickListenerImplementor (55 GREF) - backButton.Click прослушиватели
  • Задание 2 (54 GREF)
  • Намерение (54 GREF) - начало деятельности

Таким образом, как мы видим, ресурсы активности не освобождаются по окончании активности (хотя вызывается OnDestroy) Как я могу освободить все эти GREFs правильно?

1 Ответ

1 голос
/ 10 ноября 2011

Проблема в том, что в процессе присутствуют два ГХ (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 не знает - и не может знать - что есть объект Java, связанный с Object.handle, и (что более важно), сколько памяти ссылается на этот объект.

Следовательно, вам иногда нужнопомогите ему:

// 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() даст GC Mono возможность выполнить и собрать объекты мусора.После добавления этой строки, несколько раз нажав «Hello World, Click Me!»и "Back" выравнивается на 93-126 grefs (в зависимости от того, какую деятельность вы выполняете).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...