Минимизация выделения памяти с помощью обработчиков, сообщений и пакетов - PullRequest
2 голосов
/ 27 мая 2011

У меня есть activity, который постоянно (несколько раз в секунду) отправляет byte[] данные в service через AIDL.service перенаправляет эти сообщения, используя message - bundle*, в сетевой поток handler.Сетевой поток также постоянно получает данные, которые он отправляет на service handler как message - bundle.service отправляет bundle другому activities через AIDL.

Как вы можете сказать, для bundles.

выделено много памяти.выделение памяти в DDMS Я вижу, что память выделена для:

  • инициализируемого bundle
  • создаваемой хэш-карты
  • данных byte[] IЯ добавляю в качестве записи в хэш-таблицу

Я хотел бы сократить выделение памяти до минимума.

Есть ли лучший способ отправки байта [] между действиями / потоками, чем через сообщения с пакетами?

* По message - bundle, я имею в виду message с bundle в качестве данных

Попытка: создать пул из bundle объектов, но это не получилось слишком хорошо - сложно управлять междудействия, и я не знаю, как предварительно выделить его с byte[] данных ...

Ответы [ 2 ]

3 голосов
/ 27 мая 2011

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

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

Конечно, то, что является «слишком большим» или «достаточно маленьким», - это то, что вы должны протестировать в своем собственном приложении и измерить (если таковые имеются) выгоды от одного или другого подхода.

Обновление:

Дословное копирование с статьи сайта разработчика Android :

В пути с чувствительным к производительности кодом, таком как макет или метод рисованияПросмотр или логический код игры, любое распределение происходит по цене.После слишком большого количества выделений сборщик мусора включит и остановит ваше приложение, чтобы освободить память.В большинстве случаев сборка мусора происходит достаточно быстро, чтобы вы не заметили.Однако, если коллекция происходит, когда вы прокручиваете список предметов или пытаетесь победить противника в игре, вы можете внезапно увидеть снижение производительности / быстродействия приложения. Обычно сборка мусора занимает от 100 до 200 мс .Для сравнения, плавная анимация должна прорисовывать каждый кадр за 16-33 мс.Если анимация внезапно прерывается на 10 кадров, вы можете быть уверены, что ваши пользователи это заметят.

На основании вашего комментария я бы пересмотрел вопрос о том, уместен ли сборщик мусора в вашем случае.Предел кучи может варьироваться от 16 до 32 МБ (и верхний предел, вероятно, растет).Предполагая 10 выделений в секунду, 64 байта на выделение, вы будете выделять 1 МБ каждые 30 минут (приблизительно).Если для освобождения памяти ГХ требуется 200 мс, эффект будет незначительным .Я понимаю, что числа здесь не учитывают память, необходимую для хэш-карты, ни для пакета, но они все еще актуальны, чтобы дать вам представление о порядках , о которых мы говорим.Теперь рассмотрим, сколько времени сетевой запрос запрашивает для получения этих 64 байтов из сети.Даже если для этого требуется всего 50 мс, то есть от 1/4 до 1/2 времени, необходимого для GC, каждый чистый запрос .Это даже не учитывает время, необходимое вашей деятельности для обработки этих данных.

Итак, в заключение, прежде чем реструктурировать свой код в попытке повысить его эффективность, убедитесь, что шагмодификация на самом деле является узким местом, иначе все ваши усилия могут быть потрачены впустую.Просто мои 0,02 доллара.

1 голос
/ 27 мая 2011

Я часто использую пулы во встроенном материале почти по этой причине - для обеспечения некоторого «управления потоком» (если пул пуст, поток должен ждать его, пока сообщение не будет выпущено откуда-то еще), и предотвратить побег malloc / new, истощающий ту маленькую кучу, которая у меня есть. Управлять пулом проще, если каждое сообщение в пуле содержит частную ссылку на его пул. Это означает, что активность / поток не нуждается в явной передаче ссылки на пул, чтобы позволить ему выпустить сообщение обратно в пул - метод сообщения «release» может сделать это без каких-либо параметров и, если для некоторых причина в том, что существует более одного пула, нет опасности, что сообщение будет возвращено обратно в неправильный.

Rgds, Martin

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...