LINUX.ORG.RU
ФорумTalks

Жаба ест память

 , ,


0

3

Есть сервер. На нём крутятся PostgreSQL, Mongo, самописные числодробильные микросервисы, Keycloak и ActiveMQ, через который они все координируются. Когда пользователей много, запускается много экземпляров микросервисов. Память подходит к концу.

Вопрос: угадайте, кого прибьют первым по OOM?

Ответ: ActiveMQ (1G), затем Keycloak (500M). Все остальные потребляют меньше памяти.

★★★

Последнее исправление: olegd (всего исправлений: 1)
Ответ на: комментарий от anc

malloc и тому подобного в коде не встречается.
«Hello LOR » + i

У тебя каждую итерацию создается новый объект и не один.

Условно это эквивалентно:

new String("Hello LOR").concat(new Integer(i).toString())

Т.е. в простейшем случае 4 аллокации: на создание исходной строки из литерала, на создание boxed числа (в куче, т.к. полноценных value type, объявляемых на стеке, как в том же C# в яве нет), на конверсию числа в строку и на создание финальной строки.

Предположим первой аллокации не будет, т.к. «Hello LOR» интернирована. new Integer(i) до i=127 тоже не будет выделять память, т.к. эти значения кешированы. А вот оставшиеся два - будут, если там нет еще каких-то хитрых оптимизаций.

Ну а т.к. GC не работает мгновенно по выходу из scope (там у всех свои алгоритмы, у .NET например серверный GC без memory pressure особо не чешется даже), будет пила.

Midael ★★★★★
()
Ответ на: комментарий от anc
java -XX:+UseG1GC HelloLOR.java
java --version
openjdk 21.0.1 2023-10-17
OpenJDK Runtime Environment (build 21.0.1+12-29)
OpenJDK 64-Bit Server VM (build 21.0.1+12-29, mixed mode, sharing)

Жрёт 67 МБ и всё, ждал 30 секунд. Без изменений. Можно меньше памяти сделать до 50 МБ, можно ещё меньше, но там больше ключей добавлять надо.

foror ★★★★★
()
Ответ на: комментарий от DarkAmateur

Это нубские параметры. Там во-первых, можно стек меньше на тред сделать, стандартный вроде 2 МБ, а JVM кучу системных тредов запускает и из SDK даже что-то может запустить. Затем на кэши всякие классов и прочих джитов. Корочем там есть где разгуляться по флагам.

foror ★★★★★
()
Ответ на: комментарий от upcFrost

Кафка это звиздец, там взвод админов нужен, нафиг нафиг

Подразделение девопсов быстрого реагирования.

Obezyan
()
Ответ на: комментарий от foror

А давайте не будем выдумывать сложные решения там, где они не нужны. Человек хочет просто поиграться с профилировщиком на коде из 10 строк.

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 1)
Ответ на: комментарий от DarkAmateur

Я и не выдумываю:

java -XX:+UseG1GC HelloLOR.java

И не нужно эти Xmx флаги, которые носят сугубо рекомендальтельный характер для большинства GC в JVM.

foror ★★★★★
()
Ответ на: комментарий от guyvernk

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

Но главная проблема в том что люди не умеют писать на современной Java, не знают как. Корпоративное болото дает о себе знать.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)
Ответ на: комментарий от foror

Как раз нужно. Конкретно тут, чтобы увидеть работу GC не когда-то там, а пораньше. Вдруг он не нищук и у него 1Тб оперативы. Сколько он будет ждать срабатывания GC, с учётом его микрообъектов, слипов, печати в консоль?

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 2)
Ответ на: комментарий от DarkAmateur

Я не особо нищук, у меня 48 ГБ памяти и -XX:+UseG1GC из коробки поддерживает кучу от разрастания без этих нубских -Xmx вне зависимости нищук ты или нет.

foror ★★★★★
()
Ответ на: комментарий от foror

Быть может. Сойдёмся на том, что истина где-то в профилировщике.

DarkAmateur ★★★★
()
Ответ на: комментарий от DarkAmateur

Чё это? В JVM завезли годный FFI, можешь вручную памятью крутить. Просто свою реализацию строк тогда делать нужно.

foror ★★★★★
()
Ответ на: комментарий от Midael

У тебя каждую итерацию создается новый объект и не один.

Оставил только

class HelloLOR {
 public static void main(String[] args) {
  while ( true ) {
   System.out.println("Hello LOR ");
   try {
    Thread.sleep(1);
   } catch(Exception e) {
    System.out.println(e);
   }
  }
 }
}

Память течет. Что теперь я делаю не так?

anc ★★★★★
()
Ответ на: комментарий от foror

java -XX:+UseG1GC HelloLOR.java

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

ждал 30 секунд

А пользаки у вас тоже только по 30 секунд работают?

anc ★★★★★
()
Ответ на: комментарий от foror

В широком смысле, FFI --- это просто механизм. Он есть не только в Java.

DarkAmateur ★★★★
()
Ответ на: комментарий от anc

Матерящихся пользаков?

Я хз. Я «пользователь» IntelliJ, у которого код:

Java 56.9%
Kotlin 29.4%
Python 8.2%
C 2.5%
HTML 1.6%
JavaScript 0.8%
Other 0.6%

У меня память не течёт от слова «совсем». Работает днями без перезагрузок.

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 1)
Ответ на: комментарий от anc

Ну на самом деле я не знаю достоверно, что внутри Thread.sleep и System.out.println.

Надо перестать беспокоиться и начать жить.

Midael ★★★★★
()
Ответ на: комментарий от anc

Это умная GC от JDK разрабов из Oracle, вершина их научной мысли. Но ещё не по дефолту в openjdk. Должно меньше течь, может в какие-то моменты выделить памяти ещё, но потом за собой уберёт самостоятельно.

foror ★★★★★
()
Ответ на: комментарий от foror

А пользаки у вас тоже только по 30 секунд работают?

Сколько тебе надо минут, часов, дней, лет, веков?

Ну у меня сейчас uptime 16 часов исключительно из-за обновы, а так без причины не ребутаюсь.

anc ★★★★★
()
Ответ на: комментарий от Midael

Надо перестать беспокоиться и начать жить.

Слышу традиционный ответ джавистов «это не наша проблема».

anc ★★★★★
()
Ответ на: комментарий от anc

Так JVM это тот ещё конструктор. Эта хренотень твои строки ещё и кешировать может, чтобы переиспользовать:

https://stackoverflow.com/questions/3801343/what-is-string-pool-in-java

Поэтому тут вроде и кажется всё просто, но если хочешь сделать чтобы работало чётко нужно знать в 2 раза больше, чем твои малоки в обоссаных сях и прочих крестах.

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

foror ★★★★★
()
Ответ на: комментарий от foror

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

Тьфу. Я уж по началу вашего поста грешным делом подумал, что вы за жабу топите.

anc ★★★★★
()
Ответ на: комментарий от foror

java -XX:+UseG1GC HelloLOR.java

Таки растет. Было 93.7, сейчас 93.8

anc ★★★★★
()
Ответ на: комментарий от Obezyan

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

Вот я тестирую современную жабу. Но она течет.

anc ★★★★★
()
Ответ на: комментарий от DarkAmateur

Запусти Idea, запусти VisualVM, найди в VisualVM процесс Idea и открой его.

Дядь, вы все визуализируете изнутри, а не снаружи? Мне как-то интереснее то что снаружи, ибо за нее деньги плотятся, а не за показометры изнутри.

anc ★★★★★
()
Ответ на: комментарий от anc

Течет конечно, это ее архитектурная особенность, родовая травма, если хотите. Но, течет меньше чем предыдущие версии, а работает - шустрее. Т.е выше скорость на единицу утекающей памяти :)

А если серьезно, то проблема в Thread.sleep() скорее всего. лучше его заменить на TimeUnit.SECONDS.sleep(1) из java.util.concurrent.TimeUnit, Executors.newSingleThreadScheduledExecutor() или что-то подобное.

Obezyan
()
Ответ на: комментарий от anc

В таком случае, тюнячь JVM под фиксированных ресурс, но учти, там вагоны флагов. Про банальные -Xms и -Xmx уже упомянули. Если хочешь схавать всю память целиком, без ползучей аллокации, то вот ещё прикольный флаг: -XX:+AlwaysPreTouch. Использую во всяких докерах с фиксовыми ресурсами, с -Xms == -Xmx.

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 1)
Ответ на: комментарий от anc

Не. Уже 93.9 сожрала. Таки течет сучка.

ЕМНИП, то по умолчанию, JVM берёт потолок кучи в 1/4 RAM +/- на накладные расходы. Если не нищук, то твои 93.9 вообще не показатель.

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 2)
Ответ на: комментарий от Obezyan

TimeUnit.SECONDS.sleep(1)

package TimeUnit does not exist
Вы предлагаете мне что-то там ещё откуда-то скачать для того, что бы протестировать?

anc ★★★★★
()
Ответ на: комментарий от DarkAmateur

JVM берёт потолок в 1/4 RAM.

Т.е. всего 4 jvm и моей раме кердык. ЧТД.

сли не нищук, то твои 93.9 вообще не показатель.

Вы код видели? Он проще простого.

anc ★★★★★
()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от anc

А ты видел код метода println()? Thread.sleep()? JIT-компилятора? Тебе только кажется, что код простой и вообще всё просто. Там под капотом огого сколько всего. Во всяких .Net CLR всё примерно также, может даже ещё сложнее.

Ты уверен, что вот настолько надо рыть? Тогда только gdb и сборка JDK с флагом -g.

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 2)
Ответ на: комментарий от anc

Ну желательно лет 10.

У меня линух больше месяца аптайма не живёт на ноуте, когда очерденой апдейт приходит. А тебе 10 лет для джавы захотелось.

foror ★★★★★
()
Ответ на: комментарий от anc

Вы предлагаете мне что-то там ещё откуда-то скачать для того, что бы протестировать?

Тыкать джавистов носом в утечки памяти это как бить детей - слишком просто. Побежали лучше в соседнюю тему маководов троллить :)

Obezyan
()
Ответ на: комментарий от Obezyan

Но, течет меньше

Возможно, просто GC стал более продвинут, CMS заменили на G1GC.

DarkAmateur ★★★★
()
Последнее исправление: DarkAmateur (всего исправлений: 1)
Ответ на: комментарий от DarkAmateur

Ну т.е. для того что бы стать «настоящим джавистом» надо перелопатить всё днк самой jdk, а когда выйдет следующая версия начинать всё сначала. Кароший метод, не спорю. Только где вы таких «джавистов» видели?

anc ★★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)