Я играю вокруг с записью некоторых простых основанных на Spring веб-приложений и развертыванием их к Tomcat. Почти сразу я сталкиваюсь с потребностью настроить настройки Tomcat's JVM с-XX:MaxPermSize (и-Xmx и-Xms); без этого сервер легко исчерпывает пространство PermGen.
То, почему является этой такой проблемой для Java VMs по сравнению с другим, собрало "мусор" языки? Сравнивая количества "мелодии, X использований памяти" для X в Java, Ruby, Perl и Python, показывают, что Java имеет легко порядок величины больше хитов в Google, чем другие объединенные языки.
Я также интересовался бы ссылками на технические бумаги/сообщения в блоге/и т.д., объясняющие проектные решения позади JVM реализации GC через другой JVMs или по сравнению с другим интерпретируемым языком VMs (например, сравнивающие Sun или IBM JVM для Болтания как попугай). Есть ли технические причины, почему пользователи JVM все еще должны иметь дело с неавтоматической настройкой heap/permgen размеры?
Название вашего вопроса вводит в заблуждение (не специально, я знаю): Проблемы PermSize (а их много, я был одним из первых, кто диагностировал проблему Tomcat/Sun PermGen много лет назад, когда еще не было никаких знаний по этой проблеме) - это не спецификация Java, а спецификация Виртуальной машины Sun.
Если вы используете виртуальную машину, которая не использует постоянную генерацию (например, виртуальную машину IBM, если я не ошибаюсь), у вас не может быть проблем с permgen.
Таким образом, это не проблема «Java», а проблема реализации виртуальной машины Sun.
Java дает вам немного больше контроля над памятью - обратите внимание на людей, которые хотят применить , который контролирует там, против Ruby, Perl , и Python, которые дают вам меньше контроля над этим.Типичная реализация Java также очень требовательна к памяти (поскольку в ней используется более продвинутый подход к сборке мусора) по сравнению с типичными реализациями динамических языков ... но если вы посмотрите на JRuby или Jython, вы обнаружите, что это , а не проблема с языком (когда эти разные языки используют одну и ту же базовую виртуальную машину, проблемы с памятью в значительной степени выравниваются). Я не знаю широко распространенной реализации «Perl на JVM», но если она есть, я готов поспорить, что она не будет заметно отличаться по занимаемой площади от JRuby или Jython!
Это потому, что Tomcat работает на виртуальной машине Java, а другие языки либо компилируются, либо интерпретируются и запускаются на вашей реальной машине. Когда вы устанавливаете -Xmx и -Xms, вы говорите, что хотите, чтобы JVM работала как компьютер с некоторым количеством оперативной памяти где-то в заданном диапазоне.
Я думаю, что причина, по которой так много людей сталкивается с этим, заключается в том, что значения по умолчанию относительно низкие, и люди в конечном итоге довольно быстро достигают потолка по умолчанию (вместо того, чтобы ждать, пока у вас не кончится фактический баран, как это было бы с другими языками) .
Python / Perl / Ruby выделяют свою память с помощью malloc () или его оптимизации. Предел объема кучи определяется операционной системой, а не виртуальной машиной, поэтому нет необходимости в параметрах типа -Xmxn. Кроме того, сборка мусора проще и основана в основном на подсчете ссылок. Так что настраивать нужно гораздо меньше.
Более того, динамические языки обычно реализуются с помощью интерпретаторов байт-кода, а не JIT-компиляторов, поэтому они в любом случае не используются для кода, критичного к производительности.
Суть ответов @WizardOfOdds и @Alex-Martelli, похоже, верна: Java имеет расширенный набор опций GC, и иногда их нужно настраивать. Однако я все еще не совсем понимаю, зачем нужно проектировать JVM с постоянной генерацией или без нее. Я нашел кучу полезных ссылок о сборке мусора в Java, хотя и не обязательно в сравнении с другими языками с GC. Кратко:
Буду рад обновить этот ответ более подробной информацией, если она у кого-нибудь есть.