2009-08-05 2 views
11

У меня есть приложение, где профиль памяти выглядит примерно так:Стоит ли смягчать последствия сбора мусора?

Jaggy http://kupio.com/image-dump/spikeymem.png

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

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

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

Очевидно, что это также будет иметь свои собственные пределы производительности, поскольку «распределение» было бы более дорогостоящим, и на нем сохранялись бы накладные расходы.

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

+2

«большой кеш многообразных скрытых объектов» == бассейн. –

+0

pool == «Не так весело говорить»: P – izb

+3

Вы знаете, что у вас паузы? –

ответ

2

Обычно, я бы сказал, что это была работа для настройки параметров ГХ VM, то уменьшить остроконечные-Несса, но и для мобильных приложений, которые на самом деле не вариант. Поэтому, если JVms, который вы используете, не может изменить их поведение в GC, то старое модное объединение объектов может быть лучшим решением.

Библиотека Apache Commons Pool хороша для этого, хотя, если это мобильное приложение, вам могут не потребоваться служебные данные зависимости библиотеки.

6

Это похоже на шаблон flyweight, подробно описанный в книге моделей GoF (см. Ниже). Пулы объектов ушли в немилость в «обычную» виртуальную машину из-за успехов, достигнутых в сокращении создания объекта, синхронизации и накладных расходов GC. Тем не менее, они, безусловно, были вокруг в течение длительного времени, и, безусловно, хорошо, чтобы попытаться их увидеть, если они помогут!

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

Только тест скажет вам, подходит ли метод объединения для вас на ваших целевых платформах!

EDIT - я взял OP «повторно использоваться везде, где это возможно» означает, что объекты были неизменны. Конечно, это может быть не так, и мухомодный паттерн действительно связан с неизменяемыми объектами (Enum s - один из примеров мухи). Измененный (read: unshareable) объект не является кандидатом для мухи, но (конечно) для пула объектов.

+0

, который не отвечает на вопрос: должен ли он делать это – jalf

+2

Я думал, что это было неявным в ответе. Если GoF написал книгу, которая включала это как общую схему, то следует, что это потенциальное решение проблемы –

0

Вы говорите о пуле экземпляров многократного использования.

class MyObjectPool { 
    List<MyObject> free= new LinkedList<MyObject>(); 
    List<MyObject> inuse= new LinkedList<MyObject>(); 
    public MyObjectPool(int poolsize) { 
     for(int i= 0; i != poolsize; ++i) { 
      MyObject obj= new MyObject(); 
      free.add(obj); 
     } 
    } 
    pubic makeNewObject() { 
     if(free.size() == 0) { 
      MyObject obj= new MyObject(); 
      free.add(obj); 
     } 
     MyObject next= free.remove(0); 
     inuse.add(next); 
     return next; 
    } 
    public freeObject(MyObject obj) { 
     inuse.remove(obj); 
     free.add(obj); 
    } 
} 
     return in 
0

Учитывая, что ответ this говорит о том, что в J2ME не так много возможностей для настройки самой мусорной корзины, тогда, если GC является проблемой, единственным вариантом является просмотр того, как вы можете изменить свое приложение для повышения производительности/использования памяти. Возможно, некоторые из предложений в упомянутом ответе применимы к вашей заявке.

Как говорит oxbow_lakes, вы предлагаете стандартный шаблон дизайна. Однако, как и при любой оптимизации, единственный способ узнать, насколько это улучшит ваше конкретное приложение, - это реализовать и профилировать.

1

Вы можете проверить this link, описывая усовершенствования коллектора Concurrent Mark Sweep, хотя я не уверен, что он доступен для J2ME. В частности, обратите внимание:

«Совместимый с маркером коллектор, также известный как параллельный коллектор или CMS, предназначен для приложений, чувствительных к паузам сбора мусора».

... «В JDK 6 сборщик CMS может выполнять эти коллекции одновременно, чтобы избежать длительной паузы в ответ на вызов System.gc() или Runtime.getRuntime(). Gc(). эту функцию, добавьте опцию «

-XX:+ExplicitGCInvokesConcurrent 
2

На самом деле, этот график выглядит довольно здорово для меня. GC регенерирует множество объектов, и память возвращается на тот же базовый уровень. Эмпирически это означает, что GC работает эффективно.

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

2

Имеет ли J2ME коллекционный сборщик мусора? Если да, то он делает много маленьких, быстрых, коллекций и, следовательно, паузы уменьшаются. Вы могли бы попытаться уменьшить пространство памяти eden (небольшое пространство памяти), чтобы увеличить частоту и уменьшить задержку для коллекций и тем самым уменьшить паузы.

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

1

Отъезд this link. В частности:

Просто перечислить некоторые из проблем пулов объектов создают: первый неиспользуемый объект занимает пространство памяти без всякой причины; GC должен также обработать неиспользуемые объекты , задерживая их на бесполезных объектах без всякой причины; и в для получения объекта из пула объектов требуется синхронизация , которая намного медленнее , чем асинхронное распределение доступно изначально.

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

  • Нет связанных вопросов^_^