2009-05-09 4 views
49

Что именно заставляет JVM (в частности, внедрение Sun) работать медленнее, чем другие среды выполнения, такие как CPython? Мое впечатление было то, что в основном это связано с загрузкой загружаемых библиотек независимо от того, нужны они или нет, но это похоже на то, что не должно занять 10 лет.Почему JVM работает медленно?

Подумайте об этом, как время начала JVM сравнивается с CLR в Windows? Как насчет CLR Mono?

ОБНОВЛЕНИЕ: меня особенно интересует случай использования небольших утилит, соединенных вместе, как это принято в Unix. Является ли Java подходящим для этого стиля? Независимо от того, что изначально запускается Java-загрузка, она суммируется для каждого процесса Java или накладные расходы действительно проявляются только для первого процесса?

+1

Маркировка с субъективными. «Медленное» - субъективное описание. –

+20

@Martin OConnor: «медленный» субъективен, но этот вопрос не является. – Zifre

+1

AFAIK, двигатель V8 Javascript от Google для Node.js занимает около 30 миллисекунд. Я сомневаюсь, что это намного медленнее, чем JVM. Кажется, JVM занимает около 70 мс. http://tinyurl.com/phkwn45 –

ответ

18

Здесь what Wikipedia has to say on the issue (с некоторыми ссылками).

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

+0

Спасибо, статья солнца, которую вы связываете, имеет некоторые хорошие детали. – Jegschemesch

+1

Одно уточнение: это не просто (или, возможно, так много) дисковый ввод-вывод, но поиск классов изнутри банки (войн, ушей), которые представляют собой архивы zip. Извлечение занимает процессор, но особенно если они сжаты. – StaxMan

+3

Время процессора для распаковки минимально. В самом деле, stackoverflow сам использует сжатие как оптимизацию производительности, а сжатие массово дороже декомпрессии. –

1

Есть целый ряд причин:

  • много jar с загрузкой
  • проверки (убедившись, что код не делает зло)
  • JIT (как раз во время компиляции) накладные расходы

Я не уверен в CLR, но я думаю, что это часто происходит быстрее, потому что он кэширует собственную версию сборок в следующий раз (так что это не нужно JIT). CPython запускается быстрее, потому что это интерпретатор, а IIRC - не делает JIT.

+0

Классы, скомпилированные с помощью -target 1.6, намного быстрее проверяются (верификатор Harmony также намного быстрее). –

+1

CPython компилирует файлы Python в байт-код перед их исполнением, например Java. –

+0

@Bastien: существует большая разница между байт-кодом и машинным кодом. Созданный байт-код * намного проще, чем генерировать машинный код. – Zifre

5

Запуск тривиального Java-приложения с JVM-клиентом 1.6 (Java 6) кажется мгновенным на моей машине. Sun попыталась настроить клиентскую JVM для более быстрого запуска (и JVM клиента по умолчанию), поэтому, если вам не нужно много дополнительных файлов jar, тогда запуск должен быть быстрым.

+3

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

+0

Я думаю, что приложения с графическим интерфейсом - это в первую очередь то, что дало Java впечатление медленного ... Загрузка нагрузки на классы AWT и Swing, вероятно, заставляет занять хотя бы одну секунду. – Andy

4

Если вы используете HotSpot Sun для x86_64 (скомпилирован на 64 бита), обратите внимание, что текущая реализация работает только в режиме сервера, то есть она прекомпилирует каждый класс, который он загружает с полной оптимизацией, тогда как 32-битная версия также поддерживает режим клиента, который обычно откладывает оптимизацию и оптимизирует только самые загружаемые CPU, но имеет более быстрое время запуска.

См, например:

Это, как говорится, по крайней мере, на моей машине (Linux x86_64 с 64-битным ядром), то 32-разрядная версия HotSpot поддерживает как клиент и (через флаги -client и -server), но по умолчанию используется режим сервера, а 64-разрядная версия поддерживает только режим сервера.

+0

Вы уверены, что ваши данные верны: я не слышал о (современном) Sun JVM, который бы сделал полный JIT'ing для всех классов? И режим сервера определенно НЕ делает это на большинстве систем. Разница между режимами клиента и сервера больше связана с различными настройками конфигурации, такими как порог, используемый для встраивания JIT. – StaxMan

+0

Сервер HotSpot не выполняет компиляцию до 10000 итераций. Клиент делает это на 1500 человек. Однако сервер реализован несколько иначе (два вместо одного промежуточного представления, IIRC). –

1

В дополнение к уже упомянутым вопросам (классы загрузки, например, из сжатых JAR); работа в интерпретируемом режиме до того, как HotSpot компилирует часто используемый байт-код; и компиляции HotSpot, также существует довольно много одноразовых инициализаций, выполняемых самими классами JDK. Многие оптимизации выполняются в пользу более длинных систем, в которых скорость запуска меньше беспокоит.

А что касается коннеклинга в стиле unix: вы, разумеется, НЕ хотите запускать и перезапускать JVM несколько раз. Это не будет эффективным. Скорее всего, цепочка инструментов должна происходить в JVM. Это не может быть легко смешано с инструментами, отличными от Java Unix, за исключением запуска таких инструментов из JVM.

+3

(3 года слишком поздно) Он может, с помощью инструмента, такого как Nailgun! – slezica

3

Это действительно зависит от того, что вы делаете во время запуска. Если вы запускаете приложение Hello World, оно занимает 0.15 секунд на моей машине.

Однако Java лучше подходит для работы в качестве клиента или сервера/службы, что означает, что время запуска не так важно, как время соединения (около 0,025 мс) или время отклика времени в оба конца (< < 0,001 Миз).

+3

Исследование времени загрузки JVM: http://tinyurl.com/phkwn45 –

+2

@AlexMills стоит отметить, что эти исследователи использовали машину с 2006 года. Двухъядерный i3-4370 может быть на 4-5 раз быстрее. Тем не менее, их анализ, скорее всего, является актуальным. –

+0

возможно, но я полагаю, что для загрузки JVM отвечает только одно ядро. Бьюсь об заклад, SSD против HDD сделает больше различий. –

0

Все виртуальные машины с богатым типом системы, такие как Java или CLR, не будут безупречными по сравнению с менее богатыми системами, такими как те, которые находятся на C или C++. Это во многом потому, что в виртуальной машине происходит много, многие классы инициализируются и требуются работающей системой. Снимки инициализированной системы действительно помогают, но по-прежнему стоит загрузить это изображение обратно в память и т. Д.

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

6

Просто отметить некоторые решения:

Есть два механизма, которые позволяют быстрее запуска виртуальной машины Java. Первый, это механизм обмена данными класса, который поддерживается с момента обновления Java 6 Update 21 (только с VM клиента HotSpot и только с серийным сборщиком мусора, насколько я знаю)

Для его активации вам необходимо для установки -Xshare (на некоторых реализациях: -Xshareclasses) Варианты JVM.

Чтобы узнать больше об этой функции вы можете посетить: Class data sharing

Второй механизм представляет собой Java Quick Starter. Он позволяет предварительно загружать классы во время запуска ОС, см.: Java Quick Starter для более подробной информации.

 Смежные вопросы

  • Нет связанных вопросов^_^