Подтвердить что ты не робот

Почему управление памятью так заметно в Java VM?

Я играю с написанием простых веб-приложений на основе Spring и развертывания их в Tomcat. Почти сразу я столкнулся с необходимостью настроить параметры JVM Tomcat с помощью -XX: MaxPermSize (и -Xmx и -Xms); без этого сервер легко исчерпывает пространство PermGen.

Почему такая проблема для виртуальных машин Java по сравнению с другими сборщиками мусора? Сравнение подсчетов "использования памяти Tune X" для X в Java, Ruby, Perl и Python показывает, что на Java на порядок больше попаданий в Google, чем на других языках.

Мне также интересны ссылки на технические документы /blog -posts/etc, объясняющие выбор дизайна для реализации JVM GC, различных JVM или по сравнению с другими интерпретируемыми языковыми виртуальными машинами (например, сравнение Sun или IBM JVM с Parrot). Существуют ли технические причины, по которым пользователям JVM по-прежнему приходится иметь дело с неавтоматическими настройками размеров кучи/подмены?

4b9b3361

Ответ 1

Название вашего вопроса вводит в заблуждение (не специально, я знаю): проблемы PermSize (и их очень много, я был одним из первых, кто диагностировал проблему Tomcat/Sun PermGen несколько лет назад, когда пока еще не знали о проблеме) не являются спецификацией Java, а спецификацией Sun VM.

Если вы используете виртуальную машину, которая не использует постоянное поколение (например, IBM VM, если я не ошибаюсь), вы не можете иметь проблемы с permgen.

Таким образом, это не проблема "Java", а проблема внедрения Sun VM.

Ответ 2

Java дает вам немного больше контроля над памятью - ударяйте один для людей, желающих применить этот элемент управления, против Ruby, Perl и Python, что дает вам меньше контроля над этим. Обычная реализация Java также очень голодна (потому что она имеет более продвинутый подход к сборке мусора) по отношению к типичным реализациям динамических языков... но если вы посмотрите на JRuby или Jython, вы найдете ее не проблема с языком (когда эти разные языки используют одну и ту же базовую виртуальную машину, проблемы с памятью в значительной степени выравниваются). Я не знаю о распространенной реализации "Perl on JVM", но если у меня есть желание сделать ставку, это не будет заметно отличаться с точки зрения от JRuby или Jython!

Ответ 3

Python/Perl/Ruby выделяют свою память с помощью malloc() или их оптимизации. Предел для кучного пространства определяется операционной системой, а не виртуальной машиной, поэтому нет необходимости в таких параметрах, как -Xmxn. Кроме того, сбор мусора проще, основываясь главным образом на подсчете ссылок. Так что гораздо меньше, чтобы точно настроить.

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

Ответ 4

Суть ответов @WizardOfOdds и @Alex-Martelli кажется правильной: у Java есть расширенный набор параметров GC, и иногда вам нужно их настроить. Тем не менее, я все еще не совсем понимаю, почему вы можете создать JVM с постоянным поколением или без него. Я нашел кучу полезных ссылок о сборке мусора на Java, хотя и не обязательно по сравнению с другими языками с GC. Вкратце:

Счастливый, чтобы обновить этот ответ с более подробной информацией, если у кого есть их.

Ответ 5

Это потому, что Tomcat работает на виртуальной машине Java, в то время как другие языки либо скомпилированы, либо интерпретируются и выполняются против вашей реальной машины. Когда вы устанавливаете -Xmx и -Xms, вы говорите, что хотите, чтобы JVM запускался, как компьютер, с количеством помех где-то в заданном диапазоне.

Я думаю, причина, по которой так много людей сталкивается с этим, заключается в том, что значения по умолчанию относительно низки, и люди быстро достигают потолка по умолчанию довольно быстро (вместо того, чтобы ждать, пока у вас не закончится фактический барабан, как на других языках).