2013-06-02 3 views
12

Мое приложение использует GMSMapView в подвид, и использование памяти выглядит следующим образом:GMSMapView: как управлять памятью?

  • 1.25 МБ до доступа к карте;
  • 21,5 МБ после первого доступа к карте;
  • 30 MB (а иногда пики выше 30) после того, как масштабирование и панорамирование не

нет утечек, насколько я могу сказать с инструментами. Проблема в том, что я получаю предупреждения о памяти и часто отключается при отключении приложений. Очевидно, что GoogleMaps использует львиную долю в памяти приложения. Как я могу отпустить некоторые из них в didReceiveMemoryWarning()?

Возможно ли иметь Карты Google в приложении и управлять его использованием памяти, по крайней мере, достаточно, чтобы предотвратить его выключение из памяти?

Это GoogleMaps-iOS-1.3.0.

Update:

Мои рисунки памяти были далеко (использовал Отчисления инструмента вместо Activity Monitor). Ниже приведены правильные значения:

  • 8.8 MB перед доступом карты
  • 57 MB после первой доступа к карте
  • 65 MB, с шипами в районе 80 МБ. после масштабирования и панорамирования

Это явно находится в диапазоне «проблем» для ОЗУ 256 МБ (например, iPod Touch 4G) и объясняет предупреждения о памяти и случайные удары.

Неужели кто-то успешно работает с Google Maps в приложении на устройстве с 256 МБ?

+0

Попробуйте вызвать stopRendering, когда карта отсутствует на экране. Это освободит ресурсы памяти. – Felix

+0

Но что делать, когда пользователь прокручивает и масштабирует, и начинают появляться предупреждения (а иногда и выключение)? I.e., нет возможности прекратить рендеринг. Как правило, приложение просто должно позволить GMSMap привести его в банкротство памяти? :-) – user2444264

+1

@ user2444264 У вас есть решение, я столкнулся с той же проблемой –

ответ

6

API карт использует плитки размером 256 х 256 пикселей. Они загружаются в память как 32 бита на пиксель, поэтому они будут использовать 256 х 256 х 4 = 256 кб на плитку.

Если у вас есть iPad размером 1024 x 768, вам понадобится 4 x 3 = 12 плитки = 3 МБ. Однако это только в том случае, если ваше представление будет идеально согласовано с границами плитки - на практике это пересечет границы, и поэтому вам, вероятно, понадобится 5 x 4 = 20 плиток = 5 МБ.

Однако, если вы уменьшите масштаб до точки, в которой будет отображаться следующий более низкий уровень масштабирования, каждая плитка будет нарисована чуть более половины ее полного размера, и вам понадобится 10 x 8 = 80 фрагментов = 20MB.

Если у вас есть устройство Retina, оно фактически загрузит плитки следующего более высокого уровня масштабирования и, следовательно, потребует в два раза больше их в каждом измерении (в соответствии с пикселями пикселей не точек), и поэтому вам понадобится 20 x 16 = 320 плиток = 80 МБ.

Аналогичные вычисления для iPhone 5 работают до 240 плиток = 60 МБ.

Итак, если вы подсчитаете объем памяти, который требуется карте, только для плиток, не считая каких-либо накладных расходов или другой памяти, используемой для внутренней обработки, это работает довольно много. Поэтому, возможно, вы ничего не сможете сделать. Карты SDK уже освобождают неиспользуемые плитки при наличии давления в памяти - но он не может освобождать плитки, которые необходимы для отображения текущего вида.

Это означает, что единственным вариантом может быть сокращение использования памяти в вашем собственном коде.

Для моего приложения мне пришлось изменить способ работы на iPad 1, потому что у него часто не хватало памяти и сбоев. Для других устройств я нашел, что все в порядке.

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

+1

Благодарим вас за подробный ответ. Вы говорите: «Карты SDK уже освобождают неиспользуемые плитки при наличии давления памяти». Я не вижу провалов в использовании памяти в ответ на предупреждения о памяти. Я тестировал это на (256 МБ оперативной памяти) iPod Touch 4G и считаю, что вы правы, что он просто не сделает это, если я не уменьшу размер экрана. – user2444264

+0

Трудно знать наверняка, но в моем приложении я обрабатываю предупреждения о памяти, освобождая столько памяти, сколько могу, но если SDK не выпускает плитки, когда это возможно, мое приложение будет рушиться очень регулярно :) Итак, я предположим, что он выпускает плитки, когда это возможно, но есть предел того, как далеко он может продвинуться, что до сих пор довольно много. –

4

Попробуйте использовать этот код в контроллере представления:

- (void)viewWillDisappear:(BOOL)animated{ 
    [super viewWillDisappear:animated] ; 
    [m_mapView clear]; 
    [m_mapView stopRendering] ; 
    [m_mapView removeFromSuperview] ; 
    m_mapView = nil ; 
} 

Я попробовал это, и это делает высвободит некоторые GMSMapView памяти.

+0

он работает для меня .. спасибо –

+0

Я использую Swift, поэтому я не знаком с Obj-C, но я бы предложил назвать это в функции deinit, а не viewWillDisappear. – Rogoon

+0

@Rogoon Я не так хорошо знаком с Swift, но я знаю, что 'viewWillDisappear()' используется точно так же, как и в Obj-C, поэтому я не вижу смысла размещать его в другом месте. – turingtested

0

У меня также есть огромная память, используемая GMSMapview. Это серьезная проблема в google map sdk, и я думаю, что команда Google работает над этим. Они также Исправлены некоторые проблемы мелиоративных памяти в версии 1.9.0 Другие способы снижения памяти каждого конкретного

  1. уменьшить размер GMSMapView как можно меньше

  2. использования последней версии 1.9.0 - в октября 2014.

Используйте следующую ссылку для загрузки последней sdk-

https://developers.google.com/maps/documentation/ios/releases

Смежные вопросы