2015-02-09 3 views
1

Я разрабатываю приложение для целей реального времени. Чтобы решить проблему нелинейной оптимизации, я включил Java-решение jcobyla (https://github.com/cureos/jcobyla). Каждый раз при запуске решателя, сборщик мусора делает много работы со значительным выполнения:Почему сборщик мусора работает, не достигнув максимального предела кучи?

02-09 12:58:16.822: V/onCreate(7061): maxMemory:512524288k 

02-09 13:04:23.127: D/dalvikvm(7061): GC_FOR_ALLOC freed 10314K, 40% free 17304K/28544K, paused 16ms, total 16ms 

02-09 13:04:23.177: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms 

02-09 13:04:23.222: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 10ms, total 10ms 

02-09 13:04:23.322: D/dalvikvm(7061): GC_FOR_ALLOC freed 10304K, 33% free 17303K/25452K, paused 18ms, total 18ms 

>02-09 13:04:23.367: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 33% free 17303K/25452K, paused 11ms, total 11ms 

02-09 13:04:23.417: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 33% free 17303K/25452K, paused 12ms, total 12ms 

02-09 13:04:23.522: D/dalvikvm(7061): GC_FOR_ALLOC freed 10304K, 40% free 17304K/28540K, paused 16ms, total 17ms 

02-09 13:04:23.567: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms 

02-09 13:04:23.612: D/dalvikvm(7061): GC_FOR_ALLOC freed 3437K, 34% free 17304K/26196K, paused 11ms, total 11ms 

Я судимо много вещей, чтобы предотвратить GC бежать. В убеждении, что решатель достигает предела максимальной кучи приложения, я использую android:largeHeap="true". Запуск решателя в отдельном процессе не исправило его.

Как вы видите в LogTag выше, максимальный размер кучи приложения составляет около 512 МБ, что более чем достаточно для jcobyla (требуется около 300 МБ). GC говорит мне, что после запуска 34% не содержат 24,85 МБ. Общее использование ОЗУ приложения во время работы jcobyla составляет около 20 МБ.

Почему предельные значения GC отличаются от максимального предела кучи приложения?

Как увеличить возможное использование памяти для решателя?

Как предотвратить запуск GC?

ответ

2

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

GC_FOR_ALLOC означает, что Ваш запрос на выделение памяти не может быть выполнен без этапа GC и, возможно, , расширяя кучу.

которым более чем достаточно для jcobyla (требуется около 300MB)

Я понятия не имею, как вы определили, что, в частности, для Android. Более того, ваш собственный анализ утверждает, что это не так, поскольку в противном случае ваша куча выросла, по крайней мере, до 300 МБ, и это еще не так.

Почему предельные значения GC отличаются от максимального предела кучи приложения?

Поскольку куча не выросла до предела. Цель состоит в том, чтобы свести к минимуму объем оперативной памяти в системе. Чем больше процесс, тем больше Android должен прекратить другие процессы, чтобы получить все, что нужно для системного ОЗУ. Это наносит вред пользователю, например, для многозадачности.

Как увеличить возможное использование памяти для решателя?

Согласно вашему анализу, вам не нужно увеличивать возможное использование памяти для решателя.

Как я могу предотвратить запуск GC?

Прекратите использование языка программирования, который использует GC, или прекратите программирование для Android и переключитесь на некоторые настольные ОС.

Ваше приложение является одним из многих для Android, и это один из многих на любом устройстве Android.У устройств Android может быть очень мало оперативной памяти системы - на устройствах Android One, например, может быть всего 512 МБ ОЗУ. Это для ОС и для всех запущенных процессов приложений, а не только для вас. Android, в частности Dalvik/ART, создается вокруг совместной модели, где каждый процесс пытается минимизировать потребление памяти.

Но:

  • если вы пишете приложение в C/C++ с использованием NDK, не только не существует не GC, но у вас нет ограничений кучи, кроме чистого эффекта пользователей, думая, что ваш приложение вредно для их устройства из-за количества оперативной памяти системы, которое использует

  • Если вы пишете приложение для другой ОС, вы будете подчиняться этим политикам управления памятью ОС, а настольная ОС с большей вероятностью позволит вы более оперативно используете системную RAM

+1

@canScan, кроме того, Dalvik не использует движущийся сборщик мусора, поэтому, даже если у вас есть необходимое свободное пространство для размещения объекта, может быть недостаточно свободного пространства, требующего GC_FOR_ALLOC. –

+0

Спасибо за подробные ответы. @CommonsWare, использование памяти было измерено на jcobyla на настольном компьютере. Кажется, NDK - единственный способ достичь требуемой производительности. – canScan

+0

@canScan: «Использование памяти было измерено на jcobyla на настольном компьютере» - обратите внимание, что использование памяти не будет идентичным, так как время работы отличается. Как отмечает Tanis.7x, [Dalvik не имеет уплотняющего (или перемещающегося) сборщика мусора] (http://commonesware.com/blog/2014/06/16/art-garbage-collection.html), и поэтому вы можете фрагмент вашей кучи легче. Простая библиотека Java часто не оптимизирована для минимизации потребления памяти, как того требует Android-приложение (например, переработка существующих объектов, а не использование GC и свежих распределений). – CommonsWare

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