Pull to refresh

Ошибки out of perm gen space в программах на Java

Reading time2 min
Views14K
Часто при передеплое java приложений, случается ошибка OutOfMemory: PermGenSpace. Давайте разберемся что это такое, отчего она бывает, и как с этим бороться.

Что же значит эта ошибка? При работе виртуальной машины Java, классы приложения хранятся в специальной области памяти, которая называется permanent generation. Сделано это специально, ведь классы загружаются/выгражаются относительно редко, поэтому сборщик мусора вызывать для них не нужно очень часто. Существует заблуждение, что классы оттуда не выгружаются, как может показаться из названия. Это неправда, в том, что классы выгружаются, можно убедиться, подключившись к java процессу при помощи утилиты JConsole.

Давайте теперь рассмотрим причины из-за которых эти проблемы возникают. Наиболее распорстраненная из них это ошибки в программе. Где-то может болтаться нитка, запущенная под старой версией приложения, и почему-то не убитаю, какой-то листенер мог быть не удален итп. Бороться с такими проблемами относительно просто: нужно найти кто держит ссылки на старые классы при помощи профилятора. Особенно хорош тут Eclipse Memory Analyser: www.eclipse.org/mat Он легко выдерживает приложения занимающие около гигабайта памяти.

Также, в Java, есть некоторые API и библиотеки, которые приводят к утечками классов из-за обишок. Вот тут: opensource.atlassian.com/confluence/spring/display/DISC/Memory+leak+-+classloader+won't+let+go можно натйи список частых источников проблем с их решениями.

Часто, не смотря на все ухищрения, ошибка все равно вылетает, при этом в профиляторе все выглядит хорошо: на классы никто из кода приложения не ссылается, но классы почему-то не собраны. Тут скорее всего проблема состоит в особенности реализации серверной виртуальной машины, из-за которой прежде чем классы будут собраны, некоторая часть кучи будет заполнена. Проблема эта давно известна, и является одной из самых популярных проблем в Java Bug Parade: bugs.sun.com/bugdatabase/view_bug.do?bug_id=4957990 Несмотря на свою популярность, и то, что бага известна уже 9 лет, Sun поставил ей low priority, так что шансов на то, что ее скоро исправят немного.

Как же с ней можно бороться? Во первых, можно запускать приложение под клиентской виртуальной машине, при помощи свитча –client. Но этот способ не работает на 64 битных системах, где есть только сервеные виртуальные машины. Другой вариант это опытным путем подобрать значение MaxPermSize.
Tags:
Hubs:
Total votes 27: ↑25 and ↓2+23
Comments16

Articles