Каковы некоторые лучшие практики управления памятью Java? [закрытый]

У меня была похожая проблема при использовании «MultipartFormDataContent», и я бы не рекомендовал ее использовать.

Теперь я использую JSON для этого.

Вы можете найти больше информации прямо здесь: https://stackoverflow.com/a/38440832/6488079

Надеюсь, это поможет!

37
задан cherouvim 26 March 2010 в 08:40
поделиться

11 ответов

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

Книги, которые касаются этих вещей подробно (с точки зрения пользователя) Эффективный Java 2 и Шаблоны Реализации .

, Если Вы хотите узнать больше о производительности и inners VM, необходимо видеть переговоры или прочитать книги от Brian Goetz .

37
ответ дан cherouvim 27 November 2019 в 04:32
поделиться

Те два цикла эквивалентны за исключением объема something; см. этот вопрос для деталей.

Общие лучшие практики? Umm, давайте посмотрим: не храните большие объемы данных в статических переменных, если у Вас нет серьезного основания. Удалите большие объекты из наборов, когда Вы будете сделаны с ними. И ах да, "Мера, не предполагают". Используйте профилировщика для наблюдения, где память выделяется.

9
ответ дан Community 27 November 2019 в 04:32
поделиться

Нет никаких объектов, созданных в обоих из Ваших примеров кода. Вы просто устанавливаете ссылку на объект на строку, которая уже находится в arrayOfStuff. Так memorywise нет никакого различия.

8
ответ дан Kees de Kooter 27 November 2019 в 04:32
поделиться

Эти два цикла будут использовать в основном тот же объем памяти, любое различие было бы незначительно. "Представьте в виде строки, что-то" только создает ссылку на объект, не новый объект сам по себе, и таким образом любая дополнительная используемая память является маленькой. Плюс, компилятор / объединенный с JVM, вероятно, оптимизирует сгенерированный код так или иначе.

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

можно также посмотреть на Слабые ссылки и другие специализированные классы управления памятью.

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

Обновление ключ к управлению памятью является структурами данных, а также в каком количестве производительности Вы нуждаетесь / когда. Компромисс часто между циклами ЦП и памятью.

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

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

5
ответ дан Jean Barmash 27 November 2019 в 04:32
поделиться

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

Наконец, вещь № 1 необходимо постараться не делать: никогда не используйте Финализаторы. Финализаторы вмешиваются в сборку "мусора", так как объект не может быть просто освобожден, но должен быть поставлен в очередь для завершения, которое может или не может произойти. Лучше никогда не использовать финализаторы.

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

5
ответ дан Mr. Shiny and New 安宇 27 November 2019 в 04:32
поделиться

Первый цикл лучше. Поскольку

  • переменная что-то будет ясно быстрее (теоретическое)
  • , программа лучше для чтения.

, Но от точки памяти это не важно.

, Если у Вас есть проблемы памяти тогда, необходимо представить, где это используется.

4
ответ дан Horcrux7 27 November 2019 в 04:32
поделиться

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

Ваше приложение, вероятно, имеет несколько центральных структур данных. Это - те, Вы должны быть взволнованы по поводу. Например, если Вы заполняете их, предварительно выделяют их с хорошей оценкой размера, для предотвращения повторенного изменения размеров глубинной структуры. Это особенно относится StringBuffer, ArrayList, HashMap и т.п.. Разработайте свой доступ к тем структурам хорошо, таким образом, Вы не должны копировать много.

Использование надлежащие алгоритмы для доступа к структурам данных. На самом низком уровне как цикл Вы упомянули, используйте Iterator с или по крайней мере постарайтесь не звонить .size() все время. (Да, Вы спрашиваете список каждый раз вокруг, поскольку это - размер, который большую часть времени не изменяется.) BTW, я часто видел подобную ошибку с Map с. Люди выполняют итерации по keySet() и get каждое значение, вместо того, чтобы просто выполнить итерации по entrySet() во-первых. Диспетчер памяти поблагодарит Вас за дополнительные циклы ЦП.

4
ответ дан Ronald Blaschke 27 November 2019 в 04:32
поделиться

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

Большинство проблем памяти Java возникает, когда Вы храните объекты в наборе, но забываете удалять их. Иначе GC делает его задание довольно хорошим.

1
ответ дан siddhadev 27 November 2019 в 04:32
поделиться

Первый пример прекрасен. Нет никакого выделения памяти, продолжающегося там кроме выделения переменной стека и освобождения каждый раз через цикл (очень дешево и быстро).

причина состоит в том, что все, что 'выделяется', является ссылкой, которая является 4-байтовой переменной стека (в большей части систем на 32 бита так или иначе). Переменная стека 'выделяется' путем добавления к адресу памяти, представляющему вершину стека, и так очень быстрая и дешевой.

то, Чего необходимо остерегаться, - для циклов как:

for (int i = 0; i < some_large_num; i++)
{
   String something = new String();
   //do stuff with something
}

, поскольку это на самом деле делает память allocatiton.

1
ответ дан workmad3 27 November 2019 в 04:32
поделиться

Если Вы уже не имеете, я предлагаю установить Тест Eclipse & Платформа Инструментов Производительности (TPTP). Если Вы хотите вывести и осмотреть "кучу", проверьте SDK jmap и jhat инструменты. Также см. Monitoring and Managing Java SE 6 Платформенных приложений .

1
ответ дан McDowell 27 November 2019 в 04:32
поделиться

Как советовал один постер выше, используйте профилировщик для измерения использования памяти (и/или процессора) определенными частями вашей программы, а не пытайтесь угадать это. Вы можете быть удивлены тем, что обнаружите!

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

Я использую VisualVM для профилирования и очень рекомендую его. Он поставляется с дистрибутивом jdk/jre.

2
ответ дан 27 November 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: