Что это значит, если сборщик мусора «более агрессивен» в Monotouch 4? - PullRequest
2 голосов
/ 18 августа 2011

Я наткнулся на этот вопрос: Кнопка в ContentView вызывает сбой во время выполнения MonoTouch.Ошибка в Monotouch 4.0? , и у дознавателя возникли проблемы с "более агрессивным" сборщиком мусора Monotouch.

  • Может кто-нибудь объяснить, почему в случае дознавателя возникает ошибка (что собирается и почему?)?
  • Что значит «более агрессивный»?В какие ловушки я могу попасть?Чего следует избегать?
  • Что касается iOS5: Apple утверждает, что с iOS5 приложение получит одно предупреждение памяти, а затем его убьют.В отличие от любой другой версии, где приложение получило три предупреждения.Что это значит для Monotouch?Как он будет справляться с этим поведением?

Может быть, кто-то из команды Xamarin может подвести итоги о том, что можно и чего нельзя делать и дать хорошее объяснение?

В настоящее время я обновляюсь с MT3.2.6 до MT 4.1 и хотел бы просмотреть мой код и проверить, что нужно изменить.

Ответы [ 5 ]

6 голосов
/ 19 августа 2011

Мы обнаружили, что иногда разработчики сталкиваются со странными проблемами, например, диалоговые окна иногда остаются на экране, а иногда они исчезают, не оставляя следов и не объясняя, почему это произошло.

Обычно это происходит, когдавы создали UIAlertView и не сохранили ссылки на него, так как MonoTouch относился к этому объекту как к мусору (вы не ссылались на него из своего кода, поэтому у вас его не было).

Но то, как диалоговое окно исчезло с вашего экрана немедленно или позже, зависело от того, определила ли эвристика сборщика мусора, что пришло время запустить сбор.Если бы вы создали диалог сразу после коллекции, скорее всего, ваш диалог остался бы на экране.Но если вы были очень близки к коллекции, или если у вас был фоновый процесс, потребляющий память, GC сработал бы.

В общем, это сбивало с толку пользователей, "почему вещи исчезают случайно".Ответ был следующим: если вы не сохранили ссылку на него, сборщик мусора предположил, что вам все равно.

Чтобы сделать это более понятным для наших пользователей, при запуске MonoTouch в режиме отладки на симуляторе (и естьопция командной строки для управления этим для любых сборок), мы добавили поток на симуляторе, который непрерывно вызывает GC.Collect () каждые несколько секунд.Это делает более очевидным, что вы, возможно, не сохранили ссылку на ваш диалог.

Позже мы обнаружили, что очень полезным и распространенным шаблоном было держать вокруг себя два типа диалоговых окон, которые действительно имеютне использовать кроме их побочных эффектов: UIAlertView и UIActionSheet.Мы изменили MonoTouch так, чтобы он внутренне сохранял ссылки на эти два до тех пор, пока они не были отклонены.

Итак, мы получили лучшее из обоих миров: во время цикла разработки вы ловите ранее отсутствующие ссылки на нужные вам объекты, и мы взяли на себязаботиться о двух наиболее распространенных случаях, которые полезны только для их побочных эффектов.

1 голос
/ 19 августа 2011

Таким образом, после прочтения кода я не смог найти причину проблемы (и не было достаточно кода, чтобы быстро его попробовать). Теперь, если сбой был связан с UIButton, то AddSubView должен был логически сделать ссылку. Чтение документации подтвердило, что дело обстоит именно так (выделено мое):

Вид, который будет добавлен. Это представление сохраняется получателем . После добавления этот вид отображается поверх любых других подпредставлений.

Немного погуглив, я понял ошибка # 670294 , которая ссылается на стекопоток вопрос , очень похожий на тот, который вы связали. Комментарий № 22 описывает обходной путь для этой проблемы (это ошибка) и исправлен в MonoTouch 4.1.

Сейчас я не могу сказать вам, что это проблема GC, затрагивающая сам MonoTouch (одни и те же правила применимы ко всем) или не связана. Я бы предположил это связано с тем, что в качестве решения указывалось сохранение другой ссылки - , но, поскольку мне любопытно, я посмотрю исправление и добавлю комментарий позже ; -)

1 голос
/ 19 августа 2011

Это много хороших вопросов.

Об агрессивности, сборщик мусора может собирать объекты, если на них больше нет ссылок. Если он делает это медленно (назовите это пассив ), вы можете никогда не заметить некоторые ошибки, которые есть в вашем программном обеспечении.

OTOH, выполняющий приложения (многозадачность) в условиях нехватки памяти, приносит свои проблемы. Поэтому сбор данных чаще (назовите это агрессивный ) восстановит память быстрее, а может повысить общую производительность. Тем не менее, вы, скорее всего, нажмете (свои) ошибки в тех случаях, когда объекты все еще используются после того, как управляемые ссылки не удерживаются.

0 голосов
/ 19 августа 2011

Еще один ответ ...

Что касается iOS5: Apple утверждает, что с iOS5 приложение получит предупреждение памяти, а затем он будет убит. В отличие от любой другой версии до того, где приложение получило три предупреждения. Что это значит для MonoTouch? Как это справится с этим поведением?

Я не буду говорить об iOS5 (поскольку я не отслеживаю, что является публичным, а что нет). Поскольку вы не можете знать, насколько мало памяти может быть (или требуется чем-то другим), нет смысла иметь очень сложную стратегию освобождения памяти. Пользователю это нужно в другом месте, верните:)

Способ справиться с этим - переопределить DidReceiveMemoryWarning и бесплатно все , которое вы можете, например:

  • вызов GC.Collect () - это один из немногих, подходящий момент для вызова;
  • очистить любой кэш (ы), который у вас есть (например, загруженные данные, все остальное, что вы можете пересчитать позже при необходимости)
0 голосов
/ 19 августа 2011

Я тот, кто сказал, что GC был "более агрессивным" .. Это мой термин - я думаю, что Мигель смотрит на это немного по-другому.Моя интерпретация основывалась на том факте, что вещи, с которыми вы могли справиться в MT3, больше не работают (или не так надежны) в MT4.

...