Pull to refresh

Comments 18

Очень много воды.


С другой стороны, есть те, кто занимается администрированием серверов, на их сервера устанавливают JVM, отправляют jar и war-файлы, а с точки зрения мира Linux все это:

чужеродное;
проприетарное;
собирается не из исходников;
поставляется какими-то jar-архивами;
«отъедает» всю память на сервере;
вообще, ведёт себя не по-человечески.

Это что вообще за нелепое нытьё ни о чём? Если убрать ерунду, останется предложение "java-программы склонны жрать много ресурсов и сложно понять, на что они там расходуются".


По поводу остального — весьма странно проводить "сравнение" между системным менеджером памяти и менеджером памяти уровня приложения. Это примерно то же самое, как делать сравнительные таблицы между протоколами TCP и FTP. Объяснить особенности работы обоих менеджеров, приводящие к известному поведению памяти — полезная идея, но не надо было оформлять это сравнением.

с точки зрения мира Linux

Я бы вообще поставил под сомнение допустимость самой этой формулировки. Раз на Linux-сервер в принципе, с точки зрения самой ОС, а не какой-то там идеологии про «чужеродное», можно поставить JVM и можно запустить на исполнение jar и т.п. — то всё это вполне себе есть часть «мира».
К тому же всё это относится и к другим ОС. При чём тут Линукс.
Существенная проблема запуска Java-приложений на Linux — это работа с файловой системой: местоположение tmp, права на папки и файлы, лимит на файловые дескрипторы (раз уж вспомнили ulimit).

Еще не увидел ничего про StackOverflowError (threads-max, ulimit -s) — тоже популярные грабли в многопоточных приложениях.
в момент вызова этой команды у вас произойдёт форк, который. приведёт к тому, что образ JVM будет продублирован

Вот тут как-то сомнительно. А как же copy-on-write? Или совсем уж древний vfork()?
vm.overcommit_memory обычно выставлен в 0. Это примерно значит «ОС не выделит виртуальной памяти(malloc), если ей кажется что она не сможет удовлетворить последующие запросы к этой памяти». Вот чуть подробнее на примере redis'а.
Решается в простейшем случае выставлением vm.overcommit_memory в 1, но нужно понимать что после fork'а (который естественно отработает с применением технологии copy-on-write) может прийти oom_killer, если ребенок или родитель начнут активно изменять память и она фактически закончится.

Кстати в статье есть утверждение:
В ulimits есть максимальный размер памяти, который на Linux не работает, но там же есть ещё максимальный размер виртуальной памяти. Это такая интересная штука, потому что, как я уже говорил, виртуальная память — не ресурс. В принципе, от того, что я зарезервирую 100 Тбайт адресного пространства, операционной системе ни холодно ни жарко. Но ОС скорее всего не даст мне этого сделать, пока я для своего процесса не становлю соответствующий ulimit.

Вот в ней тоже неплохо бы сделать оговорку про vm.overcommit_memory mi5ha6in
Спасибо., полезно знать. Однако далее там утверждается:
Естественно, этому дочернему процессу столько памяти не нужно, просто форк делает копию всего, а уже потом освобождает ненужную память.

Все-таки в общем случае это неверно.
При «overcommit_memory = 0» ОС будет сама решать «выделить или не выделить». И делать это будет на основе прошлого поведения ПО, а не на основе того, что в коде ребенка сказано. Во всяком случае я именно так понимаю фразу на kernel.org и это согласуется с тем, что я видел на практике (если раньше бинарник запрашивал память и использовал ее, и сейчас он запрашивает еще, при том что физически столько нет, то вполне может получить NULL на свой malloc. В конце концов не просто так ведь везде пишут «проверяйте возвращаемые значения»).
Спасибо, ценное замечание
JAVA в Linux (в Windows, как правило, стандарт де-факто — JVM от самих Oracle. Там попроще, но не всегда) превращается в боль, к примеру, когда есть зоопарк серверов разной степени свежести и где Remote console сделана в виде jar-ников. И тогда начинается гуглеж… От простейшего: «запусти Java Configure, зайди в Security, добавь хост (а их в зоопарке много) в список доверенных, кильни все jvm процессы, перезапусти браузер со всеми его вкладками» до ковыряния глубоко упрятанных каких-то конфигов. При этом вероятность того, что ты в эту консоль попадешь, остается весьма низкой.
Зато увидишь много различных окон об опасности запуска подобных jar-ников:
«Файлик-то получен не из доверенного источника. Запустить?»
«О! Еще он не по https получен. Точно-точно запустить??»
«Так по https сертификатик-то такой себе… Точно-точно-точно запустить?»
«Да ну, он не соответствует моим политикам безопасности. Не запущу!» (здесь экран монитора уже разбит)

Не, можно понять обеспокоенность безопасностью запуска недоверенного софта. Но сделайте же вы кнопулечку (может и слегка спрятанную где-то в показанном диалоге о предупреждении нарушения безопасности): «Вот прям сейчас я хочу довериться этому jar-нику как самому себе, потому что мне это очень надо!!!»
Отдельного котла заслуживают те, кто встраивает ява-апплеты прямо в веб-страницу на своем сайте (хотя, к счастью, это мало сейчас уже распространено).
Широко распространено в сфере ГОСТовских ЭП/ЭЦП. Всякие госзакупки, еговы, госуслуги и тому подобное.
Java никогда не отдаёт память операционной системе
Неправда же!
Например, если используется Shenandoah GC, то память вполне может возвращаться обратно операционной системе.
UFO just landed and posted this here

В чём ваше негодование? Вы утверждаете, что сборка мусора в Linux есть?

Нет, он негодует, что в Linux его нет. Такая плохая ОС.
UFO just landed and posted this here
На слайде про вывод jstack ошибка. Идентификатор потока в Linux (LWP) – это nid. Tid это адрес объекта потока в адресном пространстве JVM.
Sign up to leave a comment.