75 маркеров на карте -> утечки памяти -> OutOfMemoryException

У меня проблема с отображением примерно 80 маркеров на карте Google. Я использую Google Maps Android API v2.

Значки маркеров являются динамическими (изменение во времени). После добавления маркера к карте невозможно изменить значок. Поэтому мне нужно удалить все маркеры и снова добавить все маркеры.

mMap.clear(); for (int i = 0; i < teams.length(); i++) { team = teams.get(i); point = new LatLng(tema.getLatitude(), team.getLongitude()); MarkerOptions marker = new MarkerOptions().position(point).title(name).icon(BitmapDescriptorFactory.fromResource(team.getMarkerId()))); mMap.addMarker(marker); } 

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

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

Я также понял, что при изменении поворота устройства с ландшафта на portait и обратно увеличивается используемая память кучи. После GC память не освобождается.

Кто-нибудь знает, неправильно ли я добавляю маркеры или сталкиваюсь с проблемой в реализации API Карт?

Я попытался воспроизвести ошибку с образцом приложения Google Map. В android-sdk/extras/google/google_play_services/samples/maps/src/com/example/mapdemo/MarkerDemoActivity.java найти маркерную демонстрацию. Ускорение тестирования я увеличил количество созданных маркеров.

 int numMarkersInRainbow = 12; 

Перейти на

 int numMarkersInRainbow = 100; 

Теперь запустите демонстрационное приложение, выберите демоверсию маркеров и несколько раз поверните вращение вашего устройства от портрета к пейзажу и обратно.

Начальная куча:

 Heap size Allocated Free %Used #Objects 11,543 BM 9,898 MB 1,645 MB 85,75% 65.982 

Куча после нескольких изменений ориентации:

 Heap size Allocated Free %Used #Objects 15,652 MB 11,337 MB 4,316 MB 72,43% 76.984 

Куча после нескольких изменений ориентации:

 Heap size Allocated Free %Used #Objects 21,312 MB 16,411 MB 4,901 MB 77,00% 111.350 

Конечным результатом будет OutOfMemoryExcpetion.

Свалка кучи показывает некоторые возможные утечки кучи: https://www.box.com/s/rsy0k22dcp267se2g1fy

Полный сброс кучи: https://www.box.com/s/6lyv2p6rlc0njqxw5zgu

Обновление: похоже, это связано с проблемой утечки памяти в Android Maps V2. См. Https://code.google.com/p/gmaps-api-issues/issues/detail?id=4766. В соответствии с этим вопросом необходимо исправить, но я сам его не тестировал.

Solutions Collecting From Web of "75 маркеров на карте -> утечки памяти -> OutOfMemoryException"

Да, вы столкнулись с очень классической и распространенной проблемой, которая поражает множество разработчиков Android … угрожающего OOM. Проблема возникает, когда вы не полностью очищаете свои старые чертежи при обновлении или ротации. Чтобы исправить это, вам действительно нужно перебирать маркеры до mMap.clear и устанавливать их в null и, возможно, запрашивать (вы не можете заставить) сборку мусора, вызывая System.gc ().

Вот один из подходов, который вы можете предпринять в качестве обходной возможности для возможной проблемы API … определить поворот устройства и удалить объект MarketOptions, установив его в null … затем повторно заполните его вашими маркерами.

Всякий раз, когда у меня возникают проблемы с утечкой памяти в моих приложениях, я просматриваю следующий сценарий

  1. Загрузите приложение
  2. Выполните операцию, которая подозревается в утечке памяти (желательно более одного раза, поэтому ее легче анализировать)
  3. Завершите приложение (нажимая назад, пока он не вернется на главный экран)
  4. Анализ дампа памяти

Шаги, которые я использую для моего анализа,

  1. Открытая гистограмма
  2. Поиск имени моего пакета
  3. Проверьте, есть ли какие-либо ссылки, которые не должны быть

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

  1. Щелкните правой кнопкой мыши на просочившемся объекте -> Список объектов -> с входящей ссылкой
  2. Выберите одну из входящих ссылок, щелкните правой кнопкой мыши -> Путь к корням GC -> исключить WeakReferences
  3. Откройте уровни стека, пока не найдете ссылку. Если единственный путь ведет к финализатору, вы слишком глубоко вырыты. Если это было неубедительно, попробуйте еще один просочившийся объект, повторите шаги.

Извините, это не точная наука, но это приведет к подсказкам, которые позволят вам легче идентифицировать пропущенный код.