Сбой отладчика MonoDevelop без сообщения об ошибке с использованием алгоритма Дейкстры и двумерного массива

Я делаю игру для iOS в Monotouch с C # и MonoDevelop. У меня очень странная авария.

Исходная информация: создание 2D-военной игры. Я реализовал алгоритм Дейкстры для расчета кратчайшего пути от источника к месту назначения с объектами между ними (пример: идти отсюда туда, но обходить машины/деревья/здания/или что-либо на пути автоматически). Мой сбой, похоже, связан с двумерным массивом байтов, который я создал для этой реализации алгоритма Дейкстры. Посмотрите это изображение, если вы никогда не слышали об алгоритме Дейкстры http://en.wikipedia.org/wiki/File:Dijkstras_progress_animation.gif

По сути, чем больше узлов в моем 2D-массиве, тем больше деталей в движении солдата на поле боя. Если я использую 2400 узлов в своем 2D-массиве, все работает/загружается нормально. Однако, если я увеличу количество узлов до 4266 для получения более подробных координат, программа вылетит при вычислении расстояний до узлов. Он завершается примерно на 30%, прежде чем падает.

Подробнее о сбое: сбой происходит только, когда я использую режим отладки/iPhone или режим выпуска/iPhone. Когда я использую симулятор отладки/iPhone, он работает нормально. И еще одно замечание: когда я создаю приложение и переношу его на свой телефон в режиме отладки/iPhone, затем останавливаю отладчик, открываю XCode Instruments, все работает нормально! Я не могу понять, почему это будет работать в симуляторе и с инструментами XCode, но НЕ с режимом Monodevelop Debug/iPhone. Делает ли XCode Instruments что-то, что «исправляет» проблему? Или отладчик MonoDevelop делает что-то, чтобы "сломать" программу?

Вот скриншот программы, работающей в XCode Instruments:

Позвольте мне объяснить, что вы видите на скриншоте. Мое приложение называется "WarGame". Глядя на временную шкалу, загрузка ЦП составляла ~ 100% от примерно 2 секунд до примерно 35 секунд. Когда загрузка ЦП падает до нуля, загрузка завершается. Таким образом, буквально потребовалось около 33 секунд, чтобы загрузить 2D-массив узлов и заполнить их расстояниями.

Имейте в виду, что в этом случае при сбое есть 4266 узлов, что означает, что 2D-массив представляет собой массив байтов [4266, 4266]. Итак, это 18 198 756 байт в 2D-массиве. И он успешно загружается при запуске XCode Instruments и успешно загружается при запуске в MonoDevelop Debug/iPhone Simulator. Но он вылетает без сообщения об ошибке при запуске в режиме отладки/iPhone на моем iPhone 4s. Использование памяти этим приложением составляет примерно 60,73 МБ, как показано на снимках экрана.

В экземпляре, который НЕ дает сбой, было 2400 узлов, что означает, что 2D-массив представляет собой массив байтов [2400, 2400]. Итак, это 5 760 000 байтов в 2D-массиве. И этот работал нормально везде.

Проблема явно заключается в том, что когда я увеличиваю количество узлов примерно до 4266 или более, программа падает. Но я не получаю сообщение об ошибке, оно просто внезапно останавливается при загрузке... Может ли это быть проблемой сборки мусора? Вы думаете, что я получу сообщение об ошибке, верно? Может ли это быть проблема "недостаточно памяти"? Но когда он загружается с помощью инструментов XCode, он говорит, что я использую только 60 МБ, а раньше я использовал до 150 МБ в этом приложении в качестве теста, поэтому я знаю, что могу по крайней мере увеличить использование памяти до 150 МБ, прежде чем он выйдет из строя с «ошибкой нехватки памяти».

Вот снимок выделения памяти из XCode InstrumentsВот снимок выделения памяти из XCode Instruments

Вот снимок страницы утечки памяти из XCode InstrumentsВот снимок страницы утечки памяти из XCode Instruments


person LampShade    schedule 26.11.2012    source источник
comment
Вы используете рекурсивный или итеративный подход? У меня были проблемы со сбоем отладчика MonoDeveloper при переполнении стека.   -  person Patrik Svensson    schedule 26.11.2012
comment
вылетает только при использовании режима Debug/iPhone или режима Release/iPhone. Работает ли сборка релиза, установленная MonoDevelop, но запущенная вручную на устройстве? или нет ?   -  person poupou    schedule 26.11.2012
comment
Релизная сборка, установленная MonoDevelop, но запущенная вручную на устройстве, НЕ работает. Однако, если я делаю выпуск сборки, установленный MonoDevelop, затем запускаю приложение с XCode Instruments, а затем закрываю приложение. Затем закройте XCode Instruments и вручную запустите приложение на устройстве, оно РАБОТАЕТ... странно, верно? Как будто есть проблема, которую XCode Instruments исправляет или обходит...   -  person LampShade    schedule 26.11.2012
comment
Рекурсивный или итеративный: я не на 100%, но я только что посмотрел примеры рекурсивных и итеративных функций, и кажется, что я использую итеративный. У меня нет функций, вызывающих себя в цикле... Но вполне возможно, что я столкнулся с проблемой переполнения стека. В любом случае, я могу видеть свой стек во время процесса сборки или во время сбоя, даже если на экране нет фактической ошибки?   -  person LampShade    schedule 26.11.2012
comment
Что касается рекурсивного или итеративного подхода, будет ли любой вызов функции внутри моего цикла считаться рекурсивным? У меня есть вызовы функций из математической библиотеки, такие как Math.Round, Math.Sqrt и Math.DivRem. Возможно ли, что вызовы функций в математической библиотеке вызывают переполнение стека, поскольку они буквально вызываются тысячи раз?   -  person LampShade    schedule 27.11.2012
comment
Рекурсивный означает, что функция вызывает сама себя, так что это вряд ли будет проблемой, если ваши функции не вызывают себя.   -  person jstedfast    schedule 28.11.2012


Ответы (1)


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

Однако вы должны иметь возможность запустить сборку выпуска вручную без проблем... как вы это делаете с инструментами Xcode.

Я подозреваю, что в игре есть более чем одна проблема. Например. запуск вашего приложения занимает слишком много времени, и сторожевой таймер убивает его (для сборки выпуска). Это по-прежнему будет работать при запуске из инструмента Xcode, поскольку он выключит сторожевой таймер.

Я не могу быть более точным без дополнительной информации (не подходит для stackoverflow). Я предлагаю вам открыть отчет об ошибке и прикрепить журналы сбоев как для отладочной сборки (запущенной MonoDevelop), так и для выпуска. build (запускается вручную).

person poupou    schedule 26.11.2012
comment
Спасибо за вашу помощь, вы попали в точку. Сторожевой таймер убивал приложение, прежде чем оно могло завершить загрузку. Я сделал тест, чтобы подтвердить это. Переполнение стека также вызывало сбой. У меня было несколько простых вызовов функций для преобразований и несколько вызовов функций математической библиотеки, которые способствовали переполнению стека. Я удалил вызовы функций и поместил весь код непосредственно в цикл. Это значительно улучшило производительность и позволило мне увеличить количество узлов в 2D-массиве. - person LampShade; 27.11.2012