Повторное использование объекта Java - PullRequest
23 голосов
/ 30 декабря 2008

Должны ли объекты Java использоваться повторно так часто, как их можно использовать повторно? Или мы должны использовать его только тогда, когда они «тяжеловесны», т. Е. Связаны ли с этим ресурсы ОС?

Все старые статьи в Интернете как можно больше говорят о повторном использовании объектов и пуле объектов, но я читал недавние статьи, в которых говорится, что new Object() в настоящее время высоко оптимизирован (10 инструкций), и повторное использование объектов не так уж сложно, как Раньше было.

Какова текущая лучшая практика и как вы, люди, делаете это?

Ответы [ 8 ]

15 голосов
/ 30 декабря 2008

Я позволил сборщику мусора сделать такое решение за меня, единственный раз, когда я достиг предела кучи для недавно выделенных объектов, был после запуска ошибочного рекурсивного алгоритма в течение пары секунд, который генерировал 3 * 27 * 27 . новые объекты так быстро, как могли.

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

14 голосов
/ 30 декабря 2008

Если вы используете их очень интенсивно и конструкция стоит дорого , вы должны стараться использовать их как можно чаще.

Если ваши объекты очень маленькие и дешевые для создания (например, Object), вы должны создать новые.

Например, база данных соединений объединяется в пул, потому что стоимость создания новой выше, чем стоимость создания. Ммхх, например, новое целое число.

Итак, ответ на ваш вопрос: использовать повторно, когда они тяжелые И используются часто (не стоит объединять объект размером 3 МБ, который используется только дважды)

Edit:

Кроме того, этот предмет из Effective Java: Неизменность избранного стоит прочитать и может иметь отношение к вашей ситуации.

8 голосов
/ 31 декабря 2008

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

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

  • Правило 1 оптимизации: не делайте этого.
  • Правило 2 (только для экспертов): пока не делайте этого.
7 голосов
/ 31 декабря 2008

Создание объектов дешево, да, но иногда не достаточно дешево.

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

Большинство улучшений производительности, которые я получил в своих проектах, были связаны либо с отказом от создания объектов, либо с отказом от всей работы (включая создание объектов) посредством агрессивного кэширования. Независимо от того, насколько велик или мал объект, все равно требуется время для его создания и управления ссылками и структурами кучи для него. (И, конечно, очистка и внутренняя дефрагментация / копирование также требуют времени.)

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

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

Моя стратегия состояла в том, чтобы просто стремиться к неизменным объектам. Неизменяемые вещи могут быть легко кэшированы и, следовательно, помогают упростить систему.

Однако, независимо от того, что вы делаете: убедитесь, что вы сначала проверили свои горячие точки с помощью профилировщика. Преждевременная оптимизация - корень зла.

3 голосов
/ 31 декабря 2008

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

Повторное использование объектов звучит как катастрофа, ожидающая, между прочим,

SomeClass someObject = new SomeClass();

someObject.doSomething();
someObject.changeState();
someObject.changeOtherState();
someObject.sendSignal();
// stuff

//re-use 
someObject.reset(); // urgh, had to put this in to support reuse
someObject.doSomethingElse(); // oh oh, this is wrong after calling changeOtherState, regardless of reset
someObject.changeState(); // crap, now this is wrong but it's not obvious yet
someObject.doImportantStuff(); // what's going on?
3 голосов
/ 31 декабря 2008

Практическое правило должно состоять в том, чтобы использовать здравый смысл и повторно использовать объекты, когда их создание потребляет значительные ресурсы , такие как ввод-вывод, сетевой трафик, соединения с БД и т. Д.

Если это просто создание нового String(), забудьте о повторном использовании, вы ничего не получите от него. Читаемость кода имеет более высокий приоритет.

1 голос
/ 31 декабря 2008

Второй вышеупомянутые комментарии.

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

Просто попробуйте написать чистый и простой код и удивитесь тому, что может сделать Hotspot.

Почему бы не использовать VisualVM или профилировщик, чтобы взглянуть на ваш код?

1 голос
/ 31 декабря 2008

Создание объектов, безусловно, быстрее, чем раньше. GC нового поколения в JDK 5 и выше также являются улучшениями.

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

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

Если бы я решил, что повторное использование объекта важно, я бы сделал это с такими продуктами, как Terracotta, Tangersol, GridGain и т. Д., И убедился, что на моем сервере было доступно большое количество памяти.

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