JVM используется память против фактической разности памяти кучи довольно высокая (G1GC) [дубликат]

Я столкнулся с рядом ограничений, связанных с подготовленным оператором:

  1. Подготовленные операторы кэшируются только внутри одного сеанса (Postgres), поэтому он действительно будет работать только с пулом соединений
  2. Множество разных подготовленных операторов, предложенных @BalusC, может привести к переполнению кеша, а ранее кэшированные операторы будут удалены
  3. Запрос должен быть оптимизирован и использовать индексы. Звучит очевидно, однако, например, заявление ANY (ARRAY ...), предложенное @Boris в одном из лучших ответов, не может использовать индексы, и запрос будет медленным, несмотря на кеширование
  4. . Подготовленный оператор также кэширует план запроса, а фактические значения любые параметры, указанные в инструкции, недоступны.

Среди предлагаемых решений я бы выбрал тот, который не уменьшает производительность запроса и уменьшает количество запросов. Это будет # 4 (партия нескольких запросов) из ссылки @Don или указание значений NULL для ненужных '?' знаки, предложенные В.Дужевым

23
задан Jim 26 May 2015 в 12:24
поделиться

3 ответа

в этой статье здесь объясняется, как GC работает на Java 7. В двух словах есть много разных сборщиков мусора. Обычно память хранится для процесса Java, и только некоторые GC выпускают ее в систему (по вашему запросу). Но память, используемая процессом Java, не будет расти бесконечно, так как существует верхний предел, определяемый опцией Xmx (обычно это 256 м, но я думаю, что это зависит от ОС / машины).

2
ответ дан francesco foresti 15 August 2018 в 18:27
поделиться
  • 1
    OP не обновляется, если куча имеет верхний предел, но если неиспользуемая часть кучи в конечном итоге восстанавливается ОС, которая будет использоваться другими процессами – Jim 26 May 2015 в 17:53
  • 2
    Я думаю, что Francesco Foresti говорит, что некоторые настройки сбора мусора приведут к сокращению кучи, и память возвращается в ОС, что я видел на практике, также, например, см. link – nsandersen 9 December 2016 в 19:01
  • 3
    дорогой ливень, не могли бы вы объяснить? – francesco foresti 23 November 2017 в 20:41

JVM в некоторых случаях освобождает память, но (по соображениям производительности) это не происходит, когда какая-либо память собирает мусор. Это также зависит от JVM, OS, сборщика мусора и т. Д. Вы можете наблюдать за потреблением памяти вашего приложения с помощью JConsole, VisualVM или другого профилировщика.

Также см. Этот отчет об ошибке , связанный с ошибкой

7
ответ дан lbalazscs 15 August 2018 в 18:27
поделиться
  • 1
    Я думаю, что вы видите из этих инструментов Java-памяти память, освобожденную в пространстве процессов Java. Но это не означает, что ОС возвращает память и может передать ее другому приложению – Jim 26 May 2015 в 13:04
  • 2
    Вы также можете увидеть общий размер кучи, но если вы не доверяете инструментам Java, вы также можете использовать собственные инструменты на уровне ОС. – lbalazscs 26 May 2015 в 13:11
  • 3
    Исправьте меня, если я ошибаюсь, но я не могу действительно вспомнить случай java-процесса, например. менеджер задач когда-либо сокращается. Но у меня нет особого опыта в мониторинге – Jim 26 May 2015 в 17:54
  • 4
    Я просто проверял, чтобы быть уверенным, и я видел, как он возвращает некоторую память! В Windows мне нравится использовать приложение vmmap (это бесплатная загрузка из Microsoft), он позволяет увидеть много интересного о использовании памяти в процессе. – lbalazscs 26 May 2015 в 20:29

HotSpot JVM выводит память обратно в ОС, но делает это неохотно, так как изменение размера кучи дорого, и предполагается, что если вам понадобится эта куча, когда вам понадобится снова.

Вы можете сделать его более агрессивным, установив -XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30, что позволит ему тратить больше времени процессора на сбор и ограничение количества выделенной, но неиспользуемой памяти кучи после цикла GC.

Предполагая, что вы используете параллельный сборщик, вы также можете установить -XX:InitiatingHeapOccupancyPercent=N с N на некоторое низкое значение, чтобы позволить GC запускать параллельные коллекции почти непрерывно, что будет потреблять еще больше циклов ЦП, но скорее сократит кучу. Этот в целом не является хорошей идеей, но на некоторых типах машин с большим количеством запасных ядер процессора, но с малой памятью, это может иметь смысл.

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

Дополнительно с Java Опция 9 -XX:-ShrinkHeapInSteps может использоваться для более жесткого применения сокращения, вызванного двумя предыдущими вариантами. Релевантная ошибка OpenJDK .

Обратите внимание, что способность к усадке и поведение зависит от выбранного сборщика мусора. Например, G1 только получил возможность вернуть неиспользуемые куски в середине кучи с помощью jdk8u20.

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

GC Logging с PrintAdaptiveSizePolicy также может обеспечить понимание, например когда JVM пытается использовать больше памяти для молодого поколения для достижения некоторых целей.

Также есть проект JEP , чтобы G1 возвращал назад память более охотно, но являлся черновиком неясно, когда и когда оно будет реализовано. Он также упоминает Shenandoah и VM OpenJ9, обладающие способностями.

33
ответ дан the8472 15 August 2018 в 18:27
поделиться
Другие вопросы по тегам:

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