Java Performance и всемогущая JVM
Что происходит на стороне Java Virtual Machine (JVM), как она влияет на производительность? Об этом и немного о Java performance в целом мы поговорили с JVM Engineer в SAP Фолькером Симонисом (Volker Simonis). Фолькер отвечал на вопросы по-английски, здесь мы публикуем перевод.
— Почему говорят, что Java медленная и проблемы производительности критичны?
— Я думаю, что восприятие Java как чего-то медлительного осталось в прошлом. В настоящее время виртуальные машины Java имеют реально навороченные JIT-компиляторы и алгоритмы сборки мусора, которые обеспечивают очень хорошую производительность для обычных приложений. Конечно, вы всегда можете найти примеры, где Java медленнее, чем нативные C/C++ приложения. Но такие системы, как Hadoop, Neo4j или H20 — примеры того, что даже большие, сложные высоконагруженные приложения могут быть написаны на Java. То есть производительность Java очень высока и как технология Java — весьма конкурентоспособна.
По моему опыту люди сегодня больше жалуются на производительность «альтернативных» языков для JVM, таких как Ruby (JRuby), Clojure или Scala. Я думаю, что JVM сможет оптимизировать их так же хорошо, как и чистый Java-код. Это лишь вопрос времени.
— Как оценивать и измерять производительность Java?
— Измерение производительности Java — это настоящая наука. Нет ничего удивительного в том, что такие компании, как Oracle, Google, Twitter или Одноклассники имеют выделенные группы по работе с производительностью, состоящие из очень опытных и квалифицированных сотрудников.
Привычные подходы профилирования производительности Java-приложений, скорее всего, всегда будут терпеть крах.
В настоящее время Java Microbenchmark Harness или, для краткости, JMH Алексея Шипилёва (обратите внимание, именно через «ё», он настаивает на этом, по крайней мере, в русскоязычных публикациях) который является частью OpenJDK, зарекомендовал себя как стандарт измерения и анализа производительности небольших и средних Java-приложений. Сложность и изобретательность реализации JMH даст вам представление о том, что JMH делает для того, чтобы точно измерить производительность приложения на Java. Его блог на http://shipilev.net/ — незаменимый источник информации по вопросам производительности и оптимизации Java.
И пока JMH, в основном, отвечает за измерение и оптимизацию производительности Java-кода, продолжает существовать проблема улучшения производительности GC. И это уже другая история, которая требует свой, другой набор инструментов и экспертизу.
— Где чаще всего бывают проблемы с производительностью?
— Это, конечно, в значительной степени зависит от типа вашего Java-приложения. Если речь о приложениях, привязанным к данным (то есть, если исполняется простой код на огромных данных), вероятно, более важно правильно выбрать и правильно настроить ваш GC-алгоритм. И даже в этом случае вам сперва придётся выбрать, хотите вы оптимизировать приложение для максимальной пропускной способности или же вы считаете более важным latency приложения.
С другой стороны, если ваше приложение зависит от вычислений, вы можете использовать инструменты типа JMH и/или нативных профайлеров, чтобы проверить, что виртуальная машина действительно полностью встраивает и оптимизирует все нагруженные исполняемые ветви.
Для жёстко распараллеленных приложений лучше выбрать правильную политику синхронизации/блокировки (которая может варьироваться в зависимости от железа/платформы, на которых работает ваше приложение) и для ввода/вывода связанных приложений важно выбрать правильную абстракцию (т.е. блокирующий vs неблокирующий) и API.
Но главное золотое правило: большая часть усилий должна быть направлена на правильность ваших алгоритмов, потому что ни одна виртуальная машина никогда не сможет превратить плохо написанный код в высокопроизводительную программу. Тонкая и точная настройка на уровне JVM, как объяснено выше, всегда должна быть только последним шагом цикла разработки.
— Вы — эксперт по JVM. Как часто JVM становится причиной низкой производительности? В чём основные проблемы и как с ними бороться?
— В идеале, после определённого количества итераций Java-приложение должно достичь состояния, при котором по меньшей мере 95% времени работает скомпилированный JIT-ом код. При этом происходят регулярные, но довольно короткие GC-паузы. Это можно легко проверить с помощью таких инструментов, как JConsole, JITwatch или Flight Recorder. Если это не так, то нужно выяснить, какая часть виртуальной машины вызывает проблему и затюнить (или заоптимизировать) соответствующий компонент VM.
Вы, может быть, знаете, что продуктовая версия HotSpot JVM предлагает около 600 так называемых расширенных опций (это те опции, которые начинаются с -ХХ), а debug-сборка включает более 1200 таких опций (чтобы получить полный список, вы можете использовать ключ -XX:+PrintFlagsFinal). С помощью этих опций вы можете получить детальную информацию о том, что происходит внутри виртуальной машины. Но самое главное, то что эти опции могут использоваться для тонкой настройки практически любой подсистемы виртуальной машины. Плохая новость заключается в том, что эти опции не очень хорошо документированы, так что, вероятно, вам придётся заглянуть в исходники, чтобы понять, что происходит на самом деле.
Некоторые проблемы со сборкой мусора могут решиться путём выбора правильного Garbage Collector (в текущей версии HotSpot их там полно) и правильной конфигурации heap-а. Проблемы производительности в сгенерированном коде часто вызываются неправильным выбором того, что нужно инлайнить. Опять-таки, это влияет в определённой степени, но, увы, это очень сложная тема и трудно добиться улучшения в одной части кода без снижения производительности других частей.
Блокировки, ожидания потоков и различные эффекты с кэшами – ещё один источник частых проблем. А вот для их решения требуется глубокое знание виртуальной машины, так же как и знание внутренностей аппаратной платформы и операционной системы.
Наконец, я хочу отметить, что в последнее время мы всё чаще видим проблемы с работой Java в виртуальных средах. JVM совершает большое количество «самоконфигураций» при запуске, чтобы оптимально адаптироваться к окружающей среде. Но вот если информация о реальных ресурсах (таких как количество CPU или объём доступной памяти), не соответствуют тому, что получила JVM, это может привести к очень плохой производительности.
Например, если операционная система рапортует о большом количестве доступных логических CPU, виртуальная машина создаст множество потоков для сборки мусора и для JIT-а. Но если хостовая операционная система будет распределять эти потоки на совсем небольшое количество физических CPU, то пользовательские потоки Java-приложения могут быть полностью вытеснены системными потоками виртуальной машины. Схожая проблема возникает, если гостевая операционная система выделяет для какой-то JVM большой объем памяти, но эта память шарится (делится) между другими гостевыми ОС.
— Как сейчас реализуются алгоритмы управления памятью в JVM, что делается для того, чтобы разработчики получали меньше проблем с производительностью?
— На самом деле, виртуальная машина HotSpot использует различные системы управления памятью и стратегии. Самая большая и самая, наверное, известная для обычного программиста на Java — это, конечно, heap плюс работающие на этом heap-е алгоритмы сборки мусора.
Однако JVM работает еще со множеством других пулов памяти. Существует metaspace, который хранит загруженные классы и кеш для хранения сгенерированного виртуальной машиной кода (самый, наверное, известный вид кода – это скомпилированные JIT-ом методы, а также сгенерированные куски интерпретатора и различные заглушки кода).
Ну и наконец, различные подсистемы виртуальной машины, такие как GC или JIT-компилятор, могут на некоторое время потребовать существенную часть нативной памяти для того, чтобы выполнить свою работу. Эта память обычно выделяется на лету и поддерживается в различных сегментах, ресурсных зонах или кэше подсистемы. Например, JIT-компиляция большого метода может временно потребовать больше гигабайта нативной памяти. Все эти пулы памяти могут быть настроены под требования конкретного приложения.
— Расскажите, пожалуйста, интересную историю из вашей практики, когда была проблема производительности Java. Как она была решена?
— Наша SAP JVM работает на множестве различных платформ, среди которых есть HP-UX на PARISC и Itanium CPU. HP-UX на Itanium обеспечивает программную эмуляцию для бинарных файлов PARISC, что делает возможным легко и прозрачно запускать приложения PARISC. Правда, на порядок медленнее, чем нативные приложения.
После того, как мы получили слишком много жалоб клиентов на очень плохую производительность нашей JVM на HP-UX/Itanium, мы стали разбираться, в чем дело. Оказалось, что клиенты использовали бинарные файлы PARISC для запуске на HP-UX/Itanium. Поскольку объяснять каждому клиенту сложности эмуляции мы не могли, мы просто добавили в очередную версию нашей JVM проверку, которая запрещает исполнение кода для PARISC в режиме программной эмуляции.
Java Performance для Enterprise
Согласитесь, неприятный момент, когда приложение вышло в продакшен и вернулось с возмущёнными замечаниями клиента по поводу торможения и зависания. Проблемы производительности Java критичны, прежде всего, для Enterprise решений. Именно поэтому за хардкорными практическими советами мы отправились к эксперту, Performance Architect в NetCracker (telecom solutions company), Владимиру Ситникову.
«О возможных проблемах производительности Java приходится слышать как в учебной, так и профессиональной среде. В каждой шутке есть доля шутки. Отчасти медлительность Java — это миф, тем более, что производительность платформы меняется со временем и то, что вызывало критику лет 10 назад, сейчас работает совершенно по-другому. Рассуждать о Java performance на уровне «тормозит — не тормозит» опрометчиво.
На практике, основные проблемы в промышленных приложениях связаны с наличием лишнего кода, когда действий выполняется больше, чем нужно для решения задачи. Где-то разработчик перемудрил, а где-то бизнес-требования так запутаны, что с первого раза быстро не напишешь. Иногда производительности железа хватает, а иногда решение работает медленнее, чем ожидалось. Основная рекомендация здесь одна — не выполнять ненужный код или хотя бы его часть.
Ещё одна причина снижения производительности кроется в алгоритмах; когда, например, используют полный перебор вместо того, чтобы найти запись по алгоритмическому признаку. Но на практике хитроумные (более умные, чем HashMap) структуры данных редко используются для повышения производительности.
Могут оказывать влияние на производительность и сторонние инструменты разработки, например, библиотеки и фреймворки. На практике проблемы могут быть на всех уровнях — и они случаются. Разработчики обычно выявляют их на тестах, проводится анализ с помощью разных техник профилирования (на уровне браузера, сервера приложений, базы данных). Проблемы со сторонним кодом возникают часто, и единственный способ отловить их — делать замеры и тщательно следить за развитием этого самого стороннего кода. В моей практике, что ни месяц, то находка. Бывает, замена одной строки кода ускоряет вставку данных в базу в 10 раз.
Вообще, главное в измерении и работе с производительностью Java — не забывать о нагрузочном тестировании. Соответственно, сколь велики и разлаписты бизнес-требования к enterprise-разработке, столь огромны тесты, которые их проверяют и помогают заметить неприятные моменты, связанные с performance. Например, нужно учитывать, что нагрузка в корпоративной среде неравномерная: утром все пришли, вошли в систему, пик нагрузки, затем к обеду идёт спад, в обед нагрузка наименьшая, а после обеда пользователи с новой силой повышают нагрузку до высоких значений. Конечно, при первом анализе такие нюансы могут быть упущены. А по факту они могут очень сильно сказываться на том, где ожидать массовой нагрузки и как писать код, чтобы избежать неприятностей с производительностью.
Вы вот меня спрашиваете про самые типичные ошибки и грабли. У каждого они свои. Например, выбор конкретной модели процессора или памяти редко что меняет. Конечно, если сравниваются образцы 2006 и 2016 годов, то модель имеет значение. Много вопросов лежит в плоскости масштабируемости. Многие находятся в поисках священного Грааля enterprise-разработки: все хотят, сделав единственный замер, предсказать, сколько нужно серверов и какой мощности для разворачивания приложения. Тут единственный выход — тестировать на живом сервере, учитывать запасы ресурсов для отказоустойчивости.
Вообще, наверное, есть универсальный инструмент оптимизации — неотвратимость тестирования. У нас в компании есть специалисты по нагрузочному тестированию и анализу результатов, но основной эффект достигается тогда, когда разработчик сам отвечает за скорость работы кода. Производительность — это не то, что можно взять и добавить постфактум. Предугадать, где будет проблема, тяжело, — подозревать каждую строку исходного кода не хватит никакого времени. Общая проблема в том, что тестирование было проведено либо не так, либо не на том объёме данных, либо не на той нагрузке и конфигурации. Например, при тестировании библиотеки не обновили, а заказчик взял и обновил — считайте, проблема пропущена.
На моей памяти были проекты, которые пробовали обойти вопрос производительности стороной, но либо это были маленькие демо-проекты, либо те, которые очень быстро возвращались с жалобами от клиентов на медленную работу приложения.
Часто к снижению производительности или падению всего приложения приводит не какая-то одна глобальная ошибка, а комбинация двух-трёх проблем, каждая из которых, на первый взгляд, не представляет угрозы. И самое страшное, что разработчик может и не узнать о проблемах, возникших в его коде. Если проблему удаётся решить силами инженеров технической поддержки, то редко ищут автора кода, чтобы «наградить» его.
Кстати, о жалобах. Если клиент негодует, чтобы понять, где искать проблему, есть простой алгоритм. Нужно спросить представителя заказчика, а как должно быть. Если всё отрабатывает медленно и вам кажется, что дело в субъективных ощущениях, уточните, за какое время должно работать. Такие требования, конечно же, лучше собирать тоже заранее (во время разработки, или до её начала). Мы требования разбиваем по компонентам: например, если пользователь хочет, чтобы страница открывалась за 5 с, мы распределяем бюджет на браузер — 1 с, на серверную часть — 3,5 с, сеть — 0,5 с и так далее. Зачастую разбивка идёт вплоть до компонентов самой системы, которые, кстати, логируют время работы, и разработчики, открыв профайлер, могут проверить укладывается ли их код в допустимые рамки.
Итак, проблемы есть. Куда смотреть, откуда ноги растут?
- Посмотреть на загруженность CPU и содержимое GC логов. Если система загружена, и при этом нагрузка вызвана работой GC, то либо памяти мало (нужно повышать -Xmx), либо «кто-то слишком много ест».
- Сама по себе 50-100% загруженность уже говорит о том, что времена отклика могут получаться самыми невообразимыми.
- Бывает, вина лежит на сторонних приложениях. Безобидное обновление может привезти пачку тормозов «в подарок». Канонический пример — история с RedHat Linux: механизм transparent huge pages вызывает проблемы с производительностью. Это «фича» Red Hat Linux, из-за которой «внезапно» начинают тормозить как java-приложения, так и базы данных. Проблеме подвержены Red Hat Linux 6+ (CentOS 6+). По ссылке можно почитать подробнее. THP режим нужно обязательно отключать. Если подобная настройка железа и программ выполняется вручную, то не исключён человеческий фактор, и в итоге — тормоза.
- Задавать классические вопросы «работало ли оно раньше» и «что меняли». Спрашивать, что делали на стороне клиента, накатывали ли обновления на компоненты системы. Если накатывали — вектор поиска становится понятнее. Если ясности нет, память свободная, тогда смотрим в профайлер, какая активность занимает ресурсы. Ну а дальше у каждого своя история со своим кодом.
Теперь посмотрим на проблему производительности поближе к реальным условиям, к клиенту. Нередко приложение совершенно неожиданно ведёт себя в продакшене, хотя на тестах всё было идеально. И этому есть объяснение. Если ситуация воспроизводится только у клиента, то это может говорить о проблеме с исходными данными. Например, мы знаем, что приложению предстоит совершать операции с 1’000’000 клиентами. Мы генерируем 1’000’000 случайных имён и фамилий, тесты проходят хорошо, поиск клиента по ФИО летает. Выходим в продакшн — пользователи негодуют. Смотрим внимательнее на проблемный поиск — и оказывается, что Ивановых Иванов Ивановичей тысяча. Если в нагрузочных тестах не учесть такое количество повторений, то немудрено, что на тестах пара найденных строк отображаются мгновенно, а в эксплуатации поиск работает через раз.
Сгенерировать корректный набор данных для тестов — целая наука. Нужно создать не просто осмысленные, допустим, 100 ГБ данных, но и учесть взаимодействия между данными — должно быть максимально похоже на то, что будет в эксплуатации.
- Идеальный случай — наличие дампа базы клиента. Его можно использовать напрямую или предварительно зашифровать. Причём шифрование должно учитывать существующие соотношения и ссылки между объектами и обеспечивать безопасность данных одновременно. Например, простая замена всех значений на MD5, не является достаточно безопасной. Даже поиск в Google по MD5 может найти «исходное» значение. Правильнее использовать HMAC, чтобы с одной стороны одинаковые данные хешировались в одинаковые хэши, но при этом дешифрация будет невозможна.
- Бывает и так, что дампа нет. В таком случае изучаются параметры будущей системы и пишутся скрипты, которые генерируют тестовые данные на основе этих параметров. При этом стоит избегать равномерных распределений, ведь, в реальности редко когда распределения равномерны.
Что ещё можно сказать о Java performance для enterprise? Собирайте нефункциональные требования заказчика: разбивку по сценариям работы, частоту взаимодействий пользователя с тем или иным модулем приложения, количество пользователей и ожидаемое время работы. Исправление проблем производительности на поздних этапах может стоить очень дорого, а лишняя секунда пока ждёт оператор колл-центра приводит к серьёзным потерям».
Если у вас возникли вопросы по высказываниям экспертов или вы хотите рассказать о своей позиции по вопросам производительности Java, добро пожаловать
Комментарии (89)
ctapnep
29.03.2016 19:32-5Уже запущенное и некоторое время работающее приложение на Java может и не очень медленно работает. Сложно сравнивать если не иметь полного аналога написанного на другом языке. Но когда мне надо провести некую операцию, которая займет 1 минуту, а для этого надо 1 минуту подождать пока запустится JVM и поднимет это самое приложение — это полный маразм. Поэтому любые десктопные приложения на Java по возможности идут в лес. А серверные… с серверными проблема не столько с производительностью, сколько с прожорливостью. Мелкое ненагруженное приложение, которое по идее должно спокойно жить на виртуалке с 128Мб памяти внезапно начинает требовать в 3-4 раза больше только из-за того оно на Java, а не на C++.
MamOn
29.03.2016 20:09+6Всё зависит от задач, но в большинстве серверных случаев, такие затраты на память с лихвой окупаются простотой разработки и лёгкостью поддержки.
ctapnep
29.03.2016 20:31-4Легкость поддержки — это, видимо, со стороны разработчика. Ибо со стороны админа таки поддерживать в живом виде проект на джаве намного сложнее, чем проект на… на чем угодно другом. А простота разработки — это не моя проблема. Мне не важно на сколько было сложно написать софт, который компания купила и мне теперь его надо хостить.
Scf
29.03.2016 22:00+3Почему столько минусов? Всё же чистая правда. JRE уже много лет шпыняют за очень медленный старт. .NET решает эту проблему продуманной модуляризацией и оффлайн компиляцией модулей. Что же касается Java, то сначала Sun, а теперь Oracle только обещают. Поэтому GUI приложения и не пишут на Java, несмотря на весьма хорошую кроссплатформенность: юзер не будет ждать 3-5 секунд после клика на иконку приложения.
С памятью получше, аккуратным тюнингом можно добиться разумных цифр, но до С++, конечно, далеко.
lany
31.03.2016 07:54+3JVM стартует 0.2-0.5 секунд с обычного HDD. Вспомним хабрасоревнование от BarsMonster. Это Java и как раз быстрая вычислительная задача. Люди соревновались из доли секунды (это включая старт JVM). Парень на третьем месте каждый тест впихнул в 0.23 секунды. Поэтому пассаж про одну минуту мне абсолютно непонятен.
ctapnep
31.03.2016 20:16-3Я не тестами занимаюсь. Я сеть с тремя сотнями юзеров поддерживаю. И вижу, что таки если приложение написано на джаве, то оно стартует (что на маке, что под виндой) в разы, если не на порядки, дольше, чем если оно нативное. Такова жизнь.
bromzh
31.03.2016 20:31+2А что за приложения?
Просто приложения на джаве обычно гигантские: IDE-шки всякие, сервера приложений. А нативные приложухи обычно поменьше. И они обычно несоизмеримы: если бы какая-нибудь нативная IDE обладала всеми возможностями джавовой, то не факт, что она запускалась бы быстрее. Так-то студия тоже долго стартует, хоть и не на джаве.ctapnep
31.03.2016 22:55+2Таки да, сложно сравнивать разные аппликушки. У меня тут по роду занятий не IDE и не сервера приложений, а всякие научные аппликушки. Каждая — единственная в своем роде. И все тормознутые до жути.
Хотя, конечно, нельзя сбрасывать со счетов вероятность, что их всех пишут левой ногой. По крайней мере багов в них море.
habradante
29.03.2016 20:09+10За плечами имею богатый опыт разработки на различных языках и могу абсолютно точно сказать что большинство проблем производительности связано с банально неоптимальным кодом на уровне работы с данными. Причем, такие «косяки» не зависят от языка.
Что интересно, именно такие горе-программисты первыми начинают искать выход в «волшебных» параметрах виртуальных машин, настройках GC и прочих подкапотных настройках.Optik
29.03.2016 23:07+1И других стеках технологий)
Диагностировать проблемы к сожалению редко кто пытается. По тыку пальца хотят решение. Беда не только программистов.
Alex_ME
29.03.2016 20:09+5Было бы интересно узнать о сравнении производительности JVM и CLR. Преимущества и недостатки, узкие места обоих.
23derevo
29.03.2016 20:42+6Если коротко, то в большинстве простых сценариев — одинаково. В сложных Java Runtime посильнее — JIT мощнее гораздо. Банально, в него гораздо больше сил вложено.
Есть еще вариант .NET с нативной компиляцией, но там тоже пилить и пилить. И натив и RyuJIT — пока сырые. Там несколько лет работы еще нужно.szKarlen
30.03.2016 12:53+2но есть вариант с C# unsafe: берешь и оптимизируешь руками :)
кстати, отстутствие техники динамической деоптимизации как HotSpot'e компенсируется тем, что все методы по-умолчанию в C# — невиртуальные, а при нехватке мощного инлайнера — ручное указание методов для этих целей.
В общем, решения есть..23derevo
30.03.2016 16:07+3да, про невиртуальность — сущая правда. В HotSpot для этого сделали спекулятивную оптимизацию: если рантайм видит только одну реализацию метода и не видит overrid-а, то он считает, что метод — невиртуальный (финальный) и генерит оптимальный код. Если же в какой-то момент приходит другая реализация того же метода, то HotSpot делает доептимизацию.
Yarikz
30.03.2016 14:38+1Учитывая, что IL сам по себе намного продвинутее Java байткода — c custom value types, не участвующими в сборке мусора, true generics без приведения типов, unsafe блоками кода с прямой манипуляцией указателями — я не понимаю, как JVM изначально может быть сильнее. На чем основано ваше утверждение?
Sirikid
30.03.2016 15:24Пока Ms добавлял сахарок в синтаксис, Oracle полировал VM.
/thread
(Вкупе с вамшим утверждением о true generics это уже холивар)szKarlen
30.03.2016 16:15в Java каждая вещь, связанная с выравниванием памяти, должна поддерживаться JVM.
Так в .NET (и это не сахар C#'a) можно спокойно выранивать структуры, чтобы предотвратить False Sharing.
Для Java пришлось ждать аннотации @Contended.
Oracle полировал VM
Это да. И сил много было брошено. Однако не все так гладко. Тот самый кейс с False Sharing'ом до 2011 года мог вызывать проблемы при маркировке объектов для GC.
Этим .NET перестал страдать, начиная c .NET 2.0 (а это 2006 год).
Nikita_Danilov
29.03.2016 20:10+2Честно говоря, не понимаю, почему все так агрессивно минусуют аргументы выше? За ними кроется вполне очевидная чья то боль, хоть и развернуты они не совсем полностью.
Ни в коем разе не пытаюсь судить что лучше/хуже, но есть один простой факт, который меня очень давно озадачивает: Задумайтесь, про любой иной язык/платформу кроме как Java/JVM, вы видите СТОЛЬКО выступлений, статей, размышлений, документации про супер-флаги (1200 штук, прекрасно), единственная цель которых это оптимизация?SerCe
29.03.2016 20:32+5Так может быть это свидетельствует о развитом коммьюнити?
sheglotron
29.03.2016 20:46+1И о существующей и ни кем не отрицаемой проблеме.
Nikita_Danilov
29.03.2016 21:27Забавно, вас тоже минуснули, видимо не всеми настолько не отрицаемой. :)
Хотя вот например общаясь со знакомыми Java разработчиками, слышу от них что они правда не видят никакой необычности во всём этом.sheglotron
29.03.2016 21:36+2Нет, совсем логично, я забыл упомянуть, что я имел ввиду конкретно desktop приложения, за что скорее всего и словил минусов. Чуть выше мы с товарищем обсуждали именно desktop приложения на java, на примере IDE. А так мой комментарий действительно выглядит как троллинг.
Nikita_Danilov
29.03.2016 21:30Ммм, то есть вы понимаете, что этим утверждением, автоматически утверждаете и что все остальные коммьюнити развиты меньше? Если не секрет, а насколько меньше они развиты?
UPDATE: Ладно, извиняюсь, не хочу начинать здесь святых войн, но мне правда интересно отношение коммьюнити Java к 1200 флагам для отладки оптимизации.23derevo
29.03.2016 21:42+7Они развиты меньше в разы. В Европе и странах СНГ существует примерно десяток больших Java-конференций: Devoxx, JavaZone, JFokus, JavaLand, Geekout, Geekon, JEEconf, Joker, JPoint.
Можете ли вы назвать какие-нибудь европейские Community-driven конференции по C/C++, Python, Ruby, .NET или любой другой конкретной технологии, собирающие например, по тысяче человек?Nikita_Danilov
29.03.2016 21:59+1Нашел сайт Lanyrd, конечно не самый точный подсчет, не знаю я размеров конференций, да и попадаются мультинаправленные конференции, но цифры интересные:
http://lanyrd.com/topics/javascript/ — past events: 1994.
http://lanyrd.com/topics/ruby/ — past events: 863.
http://lanyrd.com/topics/java/ — past events: 769.
http://lanyrd.com/topics/python/ — past events: 795.
http://lanyrd.com/topics/net/ — past events: 323.23derevo
29.03.2016 22:05+1О, спасибо за ссылки! Это интересно, на самом деле. Показывает тренды. Хотя больших конференций там мало.
Мультинаправленные большие есть, но на них много разных технологий.
По поводу JavaScript — да, это действительно самое быстрорастущее сообщество. Очень много фреймоворков и направлений, у каждого — свое сообщество :)
Labunsky
29.03.2016 22:20+13Дело даже не в конференциях, а скорее в том, что вбив в гугл вопрос практически любой сложности по джаве, можно за пару минут найти ответ, а чаще несколько и с примерами кода. На любой чих есть документация, сотни тысяч библиотек от именитых компаний вроде того же гугла или племени апачей, готовых решать за программиста (почти) любые проблемы.
В той или иной степени все это есть и в других языках, но никогда не видел чего-то настолько обширного, исключительно по своим наблюдениям.
terryP
29.03.2016 22:07+6но мне правда интересно отношение коммьюнити Java к 1200 флагам для отладки оптимизации.
Во-первых, большинство экспертов сходятся что реально нужных флагов 5, максимум 10. Во-вторых, это равносильно тому что говорить раз в Linux (условно) выходит много фиксов безопсности — она дырявая OC, а в Win (условно) мало фиксов — она супернадежная. Хотя может быть ровно наоборот, те кто забили на безопаснсоть не выпускают фиксы в принципе.
Если в каком-нибудь Visual Basic'e или PHP первой версии никто не обсуждал оптимизация, это не потому что они были супер быстрыми, а потому что не было смысла что-то оптимизировать. В случае решение вроде Hadoop'а на сотню кластеров оптимизация даже на 10% даст минус 10 серверов, вполне логично что оптимизация важна. То есть вопрос вовсе не в том что JVM медленная, вопрос в том что оптимизация JVM дает вполне реальную прибыль...
SerCe
31.03.2016 12:12+1Но вы же понимаете, что все эти флаги не с потолка взялись, они кому-то понадобились. Кто-то таки наступил на грабли, прошел все корнер-кейсы, тестил java на таких нагрузках, которые есть лишь у десятка компаний во всем мире. Некоторые флаги позволяют jvm-инженерам отлавливать такие concurrency-баги, которые встречаются у 1 пользователя из миллиона. И, в отличие от многих других платформ, эти баги действительно фиксят.
Пойнт в том, что такое количество флагов свидетельствует о взрослости платформы (Возьмем к примеру GCC, "wc — l" показал 2500+ флагов).
А то, что про эти флаги говорят и рассказывают — как раз эффект очень развитого коммьюнити.
mm7
29.03.2016 23:58В Оракле тоже были сотни параметров. Потом в процессе матерения их количество уменьшалось.
Он становился все более самонастраивающимся.
В идеале ни у сервера БД, ни у ОС, ни у Джава машины параметров быть не должно.
Она сама должна себя оптимизировать и настраивать. Наверное Джава к этому когда нибудь придет.
leventov
03.04.2016 14:27Думаю, дело в том, что если лабать самый простой и идеоматичный Java-код, он будет довольно неторопливым. Этому способствует стандартная библиотека, которая щедро аллоцирует развесистые объекты и копирует память с места на место. Как результат — 95% Java-кода работает медленно. Когда происходит затык, люди идут в Гугл или на конференции изучать производительность.
С другой стороны, на Java можно писать очень быстрое ПО, но так почти никто не делает, потому что выходит едва ли проще, чем писать на том же C++.
Некоторые пишут, что на C++ то же самое: простой код программистов "от сохи" очень неэффективный. Я не согласен с этим: стандартная библиотека C++, общая идеоматика и паттерны гораздо экономичнее, чем в Java.
Randl
29.03.2016 20:57+8Да будет срач! Забудем о том, что у каждого языка своя ниша и будем кричать "Жаба тормозит!!!11!!" и "С++ сложна! Java быстрее ассемблера если правильно прогреть JVM!!!111!".
slonopotamus
30.03.2016 09:23+2Если вы думаете, что фраза про нишы отменяет любые аргументы, это не так. Нишы эти пересекаются и на задачах, попадающих в пересечения, вполне можно производить сравнения.
Вполне может, например, оказаться, что ниша языка N полностью покрывается языками M и P (или даже одним M), причем M и P превосходят язык N в соответствующих задачах. И тогда вполне можно объявлять язык N ненужным.
Или может оказаться что ниша некоего языка Q никому нафиг не нужна.Randl
30.03.2016 09:28Java и C++ имеют свои преимущество и недостатки. Каждый из них находит свое применение и довольно широкое. Java безопаснее и обычно быстрее в разработке, C++ обычно быстрее. Это не значит что какой то язык лучше или хуже.
sunless
30.03.2016 13:59+1Мне кажется, что правильно подмечено, что работа над перформансом не начинается с подбора флажков хотспота, и не с понимания внутренностей jvm. Перформанс начинается с правильного выбора алгоритмов и структур данных, а это не относится к языку. В .net и в unmanaged языках побольше степеней свободы в выборе структур данных (java приблизится к решению этой проблемы к 10ке, когда value types допишут).
Тем, кто приходят на доклады про jvm performance, стоит помнить, что понимание внутренностей vm может помочь выжать последние несколько процентов с java приложений, в некоторых редких случаях — починить некие паталогические проблемы, но для большинства задач хватит перформанса со всеми настройками по умолчанию, лишь бы код был написан разумно.
Да и вообще, перформанс волнует небольшое количество разработчиков в процентном отношении, чаще людей волнует функциональность их приложения, то простота и корректность написания той функциональности, которую требует заказчик.
skywalk7
30.03.2016 14:39-1Java и C++ — разницу хорошо видно в сравнении Cassandra и ScyllaDB. Сцилла быстрее в 10 раз, но зато и писали её дольше во столько же раз :)
m0nstermind
30.03.2016 17:42+7Я думаю некорректно сравнивать это таким образом. Разница в быстродействии между ними обусловлена в первую очередь не языком, а архитектурой процесса обработки запросов. В Cassandra — это SEDA (https://en.wikipedia.org/wiki/Staged_event-driven_architecture), что позволяет хорошо регулировать нагрузку на систему, что в свою очередь, дает возможность получить устойчивую работу системы под разной нагрузкой. Но, при этом приводит к многоэтапной обработке каждого запроса, большому количеству внутренних очередей, и, как следствие, переключений контекта и невысокое быстродействие.
В scylla — процесс обработки запроса построен по Seastar (http://www.scylladb.com/technology/architecture/) — оптимизирован для разделения задач по корам и сетевым картам. Как следствие, количество переключений контекста сильно минимизировано, можно достичь большого красивого быстродействия. Особенно в ситуации, когда синтетический тест ставится на наборе данных полностью помещающемся в память.
m0nstermind
04.04.2016 11:46+2Неплохой, кстати, обзор на тему сравнения C vs java от Клиффа Клика можно посмотреть тут: http://www.infoq.com/presentations/java-vs-c-performance
waxtah
30.03.2016 14:40+1Последние несколько лет работаю с этим чудесным языком, и вполне доволен им. Я решал задачи с projecteuler.net на разных языках, и разница в производительности между c / java у меня получалась от 10% до 30%, согласитесь это не такая уж и большая разница. А наличие в java из коробки коллекций позволяет к ряду задач находить решение на порядок быстрее (можно легко реализовать кэширование вычислений или с BigDecimal можно оперировать большими числами).
Если у вас проблемы с производительностью на java, то скорее всего вы что-то делаете не так.real_ales
30.03.2016 14:42+2Ну либо задача стоит такая, что вам приходится выжимать эти несчастные доли процента перфоманса из приложения. Однако какой бы нагруженный BigData/HFT проект ни был, перфоманс начинается с архитектуры. Аминь.
CyberSoft
31.03.2016 11:22У нас тут своя, нехорошая история с GC.
Поставили как-то кластер Elasticsearch на десяток машин, при этом решили посмотреть, как будет вести себя G1. Кластер работал… пару дней, дальше перезапуск, из-за появлявшейся тормозящей кластер ноды по каким-то до сих пор невыясненным причинам.
Симптом: все потоки для балков прожигали время в таблице TheadLocal.ThreadLocalMap.table. Судя по дампам, таблица разрасталась и имела большой диапазон идущих подряд Entry, на которых как раз спотыкается цикл в методе ThreadLocalMap.expungeStaleEntry() (видимо тот самый цикл, что unlike Knuth). Вычеркнуть пытался ReentrantReadWriteLock всего лишь свой readHolds. Ну и вообще, в хот-тредах эластика часто появлялись методы ThreadLocalMap, вроде getEntryAfterMiss(), долго работающие с этой разросшейся таблицей.
На GC не думали, конечно, искали баги в коде… пока не сменили сначала на дефолтовый, потом на CMS. В обоих случаях проблем не было, только при G1 проявлялась такая проблема. Гадай теперь, что виновато: алгоритмы, тюнинг или железо.23derevo
31.03.2016 11:46а Java у вас какая?
CyberSoft
31.03.2016 12:11Восьмая, конкретно 1.8.0_72
23derevo
31.03.2016 12:18а баг против G1 завели в JBS?
CyberSoft
31.03.2016 12:38На днях только закончили страдать с этой проблемой, а так да, надо бы. Вот только джава оракловая, как того рекомендует Elasticsearch.
lany
31.03.2016 12:40Это нестрашно, всё равно туда пишите. Если аккаунта нет, то сюда:
http://bugreport.java.com/
amarao
Все рассказы о производительности java натыкаются на одну смешную истину: на java не написано ни одного более-менее вменяемого браузера. Вот когда напишут — вот тогда можно будет посмотреть, кто быстрее. Без всяких кивков в сторону gc, "неправильно готовят" и т.д.
До этого момента java идёт в одном ряду с другими "песочными" языками класса перла, питона, руби и т.д., которые хороши для мелкоприкладной разработки но совершенно не готовы к системам с требованиями высокой производительности.
23derevo
Количество браузеров, написанных на той или иной платформе — это очень странная метрика популярности. Последние лет 10 речь в мире идет про серверную Java, поэтому я плохо понимаю, что вы тут такое вообще написали :)
bromzh
На чистом С и фортране тоже ни одного браузера.
Sirikid
Если используется WebKit браузер уже на C++?
terryP
А можно список языков, кроме С++, на которых написаны более-менее вменяемые браузеры? Насколько я знаю, на D, Go, Rust тоже не написано ни одного вменяемого браузера, тоже производительность виновата? Всех популярных вменяемых браузеров штук пять-шесть, наверное, да и то большая часть клоны друг друга.
sheglotron
Автор комментария выше, скорее всего пенял на производительность GUI Java приложений, в частности, популярных IDE. Я с ним согласен, работаю только в vim или sublime, т.к. IDE на Java для меня очень прожорливые, жрут ресурсы как игры 2008 года. Тот же Sublime с плагинами под IDE работает в разы быстрее как с обычными задачами, так и с задачами с файловой системой и с сетью.
terryP
IDEA жрет много ресурсов из-за умных автоподстановок и прочих умных плюшек, При желании можно все отключить, но тогда главные плюсы IDEA теряются.
Satus
Ага, только вот научили бы бы они ещё дебагер не виснуть по 5 секунд на брейкпоинте, было бы чудесно.
Terranz
а ещё можно разрабатывать на компьютере мощнее чем микроволновка
Satus
i5 3770k, 8Gb RAM, что я делаю не так? Просто в CLion дебаггер такой, они сами об этом писали и пытаются исправлять.
Indexator
Справедливости ради, микроволновка — достаточно мощный прибор, впрочем, как и чайник… :)
dimykus
А servo?
1nsidE
ладно, а сколько на java написано 3d движков? сколько HFT систем в бекенде исползуют java? вы видели GUI которые написаны на java и которые тормозят? мне неизвестны числодробилки/реал-тайм (привет GC) приложения на java, в основном java исползуется для написания приложений которые большую часть времени ждут I/O (диск/сеть), если я не прав, прошу меня поправить :)
По моему скромному мнению java популярна по причине легкости обучения и относительной сложностью выстрелить себе в ногу.
P.S.
Есть проект Cassandra DB переписанной на C++ (http://www.scylladb.com/), так авторы заявляют о 10х кратном приросте производительности.
terryP
достаточно
а их много, научные числодробилки, базы данных и nosql хранилища, поисковые системы, машинное обучение и нейроные сети и т.п.
Есть специальные JVM для реал-тайм, где нет остановки мира от слова совсем
Ну, так то авторы, они и стократный прирост заявят. Если бы так просто было бы получить такой прирост никто бы даже не начинал писать Cassandra DB и ей подобные базы данных на Java. Опять-таки Hadoop и прочий BigData это как раз числодробилки.
P.S. Естественно, у Java тоже есть предел и для ряда задач C и С++ будут лучше, тем не менее есть очень много задач (в том числе по обработке данных) в которых разница между производительностью Java и C++ не так существенна, как разница в затраченных ресурсах разработчкиов. Собственно есть ряд задач где С лучше С++, а есть где рулит только ассемблер.
Ckpyt
Да-да, играл я в игрушки на Jave. Тот же Wurm-онлайн. Графика середины 2010-х, а ресурсы кушает как последний фаркрай.
Есть и другие проекты на Jave — Salem Online, Hafen — у всех у них БОЛЬШИЕ проблемы с графикой и очень большие с прожорливостью.
Так что, про триДэ на яве — не надо, нет его вменяемого.
Razaz
.Net? Та же Java только в профиль. Очень активно используется в игроиндустрии.
DarthVictor
Справедливости ради 3d движков по ссылки три, а успешных в лучшем случае полтора. А пригодных для игр AAA-класса — ноль.
Есть с предсказуемой задержкой (до 1мс). При этом Oracle разработку таких версий свернул в 2012, а у других вендоров версия JVM в лучшем случае седьмая (у IBM), а то и вообще шестая (JamaicaVM). Плюс версии эти дорогии, так что для ускорения работы уютненькой питерской Идейки подходят слабо. А тем у кого есть деньги зачастую проще взять сишника с опытом.
Ну, Майнкрафт же написали.
Тут нужно понять, что вы понимает под числодробилками. Я думал это скорее всякие аудио/видео кодеки, архиваторы, всякие мат. библиотеки. Тут плюсы и фортран все-таки вне конкуренции.
http://lessthanoptimal.github.io/Java-Matrix-Benchmark/runtime/2015_07_XeonQuad/
http://stackoverflow.com/questions/529457/performance-of-java-matrix-math-libraries
Другое дело что мне не известно ничего написанного не на C++/C/Fortran, что работало бы быстрее. Хотя нет, вру CLR имеет первый старт субьективно побыстрее, в остальном у него даже скорость GUI не лучше, хотя GUI у него некроссплатформенный и гвоздями прибит к WinAPI. А объяснение простое — нулевая стоимость абстракций — это не пустой звук, а здесь у "сей" ("плоских" и с "крестами") конкурентов пока нет. В теории Rust еще может к ним может когда-нибудь добавиться. При этом Rust объективно сложнее Java.
terryP
Ну из той же справедливости, если верить вики , то на чем-то кроме C++/C движков практически и нет (в частности в списке нет ни Go, ни D, ни Rust). Вообще это не совсем правильный критерий, использование ЯП в какой-то области далеко не всегда зависит от производительности и возможностей языка, основное все-таки наличие уже готовых разработок, большого количества разработчиков и т.п. Нечестно же сравнивать, например, кол-во игров для Андроида на Java и других языках, потому что понятно что у Java будет преимущества нативного ЯП.
Ну, кстати нет, такие задачи тоже не числодробилки. Были у меня подобные задачи на Java, там тоже все упиралось в скорость диска, то есть пока архивированный поток читается/пишется, его успевают и разархивировать и обработать и заново заархивировать в параллельном потоке и ещё полно времени остается.
P.S. Я не спорю, задачи где производительности Java может не хватить бывают, но их не так много как кажется, в большинстве случаев все (базы данных, кодеки, архиваторы, биг дата) всё равно чаще упирается в скорость диска или сети, то есть тормозит в первую очередь от кривой архитектуры или кривых рук.
Terranz
справедливости ради
суперуспешный майнкрафт написан на джаве, все волками выли от тормозов, пишут патчи для оптимизации, но играют
Maccimo
У вас с аргумента жЫр стекает.
rauch
все ваши аргументы рассыпаются после поверки IDE.
Все лучшее, что есть — построено на опыте IntellijIDEA, пупсик
Randl
И тормозит на больших проектах, как бы я не обожал Clion
terryP
Тормозит потому что в IntellijIDEA очень умная система автоподстановок и т.п. умных штук, IDEA очень часто догадывается о том что хочет программист, но это сжирает дофига ресурсов. Поотключать это можно и тормозить не будет, другое дело что это практически главное преимущество этой IDE. Тут несколько некоректно сравнивать IDEA с просто продвинутыми редакторами, так как в них всех умных штук просто нет.
Randl
Да ладно. KDevelop и Qt Creator предлагают +- тот же самый набор фич.
terryP
Там не в фичах дело, не знаю насколько это явно в Clion, но в Java IDEA умудряется практически угадывать что сейчас напишет программист и давать умные подстановки имен, типов и методов, что дико облегчает разработку, ни в одной другой IDEA такого удобства не видел. ИМХО, я вполне понимаю на что уходит производительность и меня такая "цена" вполне устраивает (лучше я куплю более дорогой комп, но буду на 20% продуктивнее, чем наоборот).
Randl
И как это реализовано? Магией или всё-таки фичами?)
У меня само написание кода занимает не такой большой промежуток времени. Конечно иногда доводится строчить код практически безостановочно, но в среднем у меня ощущение, что тобы ускориться на 20% надо чтоб код набирался сам и мгновенно.
Кроме того, особо крупные проекты там тормозят(тормозили?) даже на топовой конфигурации. И что? Двухпроцессорник собирать? На ноуте даже не мечтать IDE запустить?
Если холиварить, то на С++ оно наверняка бы не тормозило. Я уверен. Если холиварить с самим собой, за те же деньги и время на С++ подобное написать наверняка невозможно. Что возвращает нас к вопросу о том, что у каждого языка своя ниша, и утверждение Java круче C++ (как и обратное) смысла не имеет. Но любой кулик, как известно, своё болото хвалит...
23derevo
а вы сколько багов против них завели?
Randl
Завел в основном фич реквесты, под багами комметирую, привожу способы воспроизведения, etc.
funi
На протяжении всего интервью подчеркивается то, что, чтобы Java была по-настоящему высокопроизводительной ее нужно тонко настраивать под каждую конкретную систему, что неприемлимо для десктоп-приложений.
Foror
Нужно понимать, что джава занимает свою нишу и не предоставляет программисту низкоуровневых фич для написания браузеров или ОС. Хотя тенденции идут к тому, что в 10-ке (думаю конец 2017 года уже будут тестовые сборки) программисты получат низкоуровневые фичи. Вплоть до инлайна машинных кодов в методы классов и дешевый вызов функций из нативных библиотек. Что сделает реальностью написание браузера на джаве.
А ставить на один уровень джаву с перлам и питонами — попахивает любительством в области разработки ПО. Я бы вас еще понял, если сравнение шло с Go, D или подобными ЯП.
CyberSoft
Зато на java написан Elasticsearch, который мы сейчас используем на большом кластере. Ничего, работает, я бы сказал отлично :) Можете сказать, что если переписать его на, то мы сэкономили бы парочку серверов. Но нет, он есть только на джаве.
CyberSoft
Хотел сказать "переписать его на ваш любимы язык"
NLO
НЛО прилетело и опубликовало эту надпись здесь
CyberSoft
Кстати, это на десктопе нет, а как же J2ME (земля пухом) и андроид? Не знаю как на андроиде, там всё-таки можно взять C/C++, но J2ME? А как же Opera Mini? Там было даже немного яваскрипта :D
Да ей наверно до сих пор пользуются. И это на кирпичиках с около 2мб хипа. Как раз "более-менее вменяемый браузер" на java :)
Onkami
и давно у вас браузер — мерило всего? Вообще, налицо недопустимая для технически грамотного человека подмена понятий
не написано браузера — значит почему-то «не готовы к системам highload»
при этом куча бирж работает на java, есть такие вещи как disruptor и chronicle, люди умеют обрабатывать миллион сообщений в секунду на этой самой яве, а вы явно не в теме. Сайт LMAX-exchange вам в помощь.
Последний раз, когда я видел высказывание «на яве нельзя работать с финансами», это было в блоге чувака, который… нигде сам не работает, а свои сведения почерпнул, сходив на интервью в фирму, где на яве таки работали с финансами.
И вообще это просто язык.