Исключение Java OutOfMemory: ошибка mmap при загрузке zip файла

Я запускаю свое приложение для создания env (rhel 5.2 x64, oracle jre 1.7_05, tomcat 7.0.28) с аргументами JVM:

-Xms8192m -Xmx8192m -XX:MaxPermSize=1024m 
-Doracle.net.tns_admin=/var/ora_net -XX:ReservedCodeCacheSize=512m -XX:+AggressiveOpts -XX:+UseFastAccessorMethods 
-XX:+UseStringCache -XX:+OptimizeStringConcat -XX:+UseCompressedOops -XX:+UseG1GC -Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9026 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

Через несколько секунд у меня есть трассировка стека:

Java HotSpot(TM) 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
Java HotSpot(TM) 64-Bit Server VM warning: Attempt to allocate stack guard pages failed.
mmap failed for CEN and END part of zip file
[...]
Caused by: java.lang.OutOfMemoryError: null
    at java.util.zip.ZipFile.$$YJP$$open(Native Method) ~[na:1.7.0_05]
    at java.util.zip.ZipFile.open(Unknown Source) ~[na:1.7.0_05]
    at java.util.zip.ZipFile.<init>(Unknown Source) ~[na:1.7.0_05]
    at java.util.zip.ZipFile.<init>(Unknown Source) ~[na:1.7.0_05]
    at java.util.jar.JarFile.<init>(Unknown Source) ~[na:1.7.0_05]
    at java.util.jar.JarFile.<init>(Unknown Source) ~[na:1.7.0_05]
    at sun.net.www.protocol.jar.URLJarFile.<init>(Unknown Source) ~[na:1.7.0_05]
    at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source) ~[na:1.7.0_05]
    at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source) ~[na:1.7.0_05]
    at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source) ~[na:1.7.0_05]
    at sun.net.www.protocol.jar.JarURLConnection.getInputStream(Unknown Source) ~[na:1.7.0_05]
    at java.net.URL.openStream(Unknown Source) ~[na:1.7.0_05]
    at org.apache.catalina.loader.WebappClassLoader.findLoadedResource(WebappClassLoader.java:3279) ~[na:na]
    at org.apache.catalina.loader.WebappClassLoader.getResourceAsStream(WebappClassLoader.java:1478) ~[na:na]
    at org.apache.http.util.VersionInfo.loadVersionInfo(VersionInfo.java:242) ~[httpcore-4.2.jar:4.2]
    at org.apache.http.impl.client.DefaultHttpClient.setDefaultHttpParams(DefaultHttpClient.java:180) ~[httpclient-4.2.jar:4.2]
    at org.apache.http.impl.client.DefaultHttpClient.createHttpParams(DefaultHttpClient.java:158) ~[httpclient-4.2.jar:4.2]
    at org.apache.http.impl.client.AbstractHttpClient.getParams(AbstractHttpClient.java:448) ~[httpclient-4.2.jar:4.2]

Глядя на мой профилировщик - все в порядке (память кучи и не кучи используется на 10%), и я понятия не имею, где проблема.

Эта проблема происходит каждый день в одно и то же время и не связана с временем простоя приложения. В чем причина проблемы?

Отредактировано:

Новый вывод в файле журнала:

Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=
Code Cache  [0x00002aaaab790000, 0x00002aaaad240000, 0x00002aaacb790000)
 total_blobs=4223 nmethods=3457 adapters=707 free_code_cache=497085Kb largest_free_block=508887936

Но у меня достаточно памяти: http://i.stack.imgur.com/K8VMx.jpg

Ответ: Проблема в java-версии. Он описал здесь: https://forums.oracle.com/forums/thread.jspa?messageID=10369413

Ответ 1

Я видел эту ошибку до того, как закончилась нехватка ресурсов, например, из-за нехватки пространства подкачки или нехватки памяти. Посмотрите sudo cat /proc/$PID/maps | wc -l по сравнению с cat /proc/sys/vm/max_map_count

См. комментарии ниже.


Я также предложил....

Кажется, что вы столкнулись с ошибкой с YourKit. Какую версию вы используете?

Я бы сбил большинство ваших опций, поскольку они либо по умолчанию, либо ничего не делают или могут усложнять ситуацию.

-mx8g -XX:MaxPermSize=1g -Doracle.net.tns_admin=/var/ora_net 
-XX:ReservedCodeCacheSize=512m -XX:+UseG1GC -Dcom.sun.management.jmxremote.port=9026

Я бы попробовал сбросить -XX:+UseG1GC, а также это относительно новый сборщик и не должен изменять ваши результаты.

Ответ 2

Не уверен, что изменилось в Java 1.7, как я помню из Java 1.6, мы используем опции Xms, как показано ниже.

  -Xms=512m -Xmx=512m

Ответ 3

Попробуйте эти параметры

-Xrunhprof:heap=all,depth=12,cutoff=0

Это создаст файл дампа в корне приложения. Позже вы можете проанализировать с помощью HP Jmeter. Это даст мгновенный снимок того, что произошло с вашим 8Gigs памяти. Вы можете ознакомиться с руководствами HP JMeter здесь.

Также выбрал ваши варианты Xrunhprof с умом. Вышеупомянутый вариант, который я упомянул, создаст огромный файл дампа. Из руководств вы можете найти подходящие варианты.

Ответ 4

Некоторые параграфы оригинальной статьи блога, это объясняет, как работает java jar/zip:

Ошибка OOM запускается во время нативного вызова (ZipFile.open(Native Method)) из JDK ZipFile для загрузки нашего EAR файла приложения. Эта собственная операция JVM требует наличия собственной собственной памяти и виртуального адресного пространства для выполнения операции загрузки. Вывод на этом этапе состоял в том, что на нашей виртуальной машине Java VM 1.5 на время развертывания заканчивалось собственное пространство памяти/виртуального адреса.

Встроенная память Java Java и файлы MMAP

При использовании JDK 1.4/1.5 любой JAR/ZIP файл, загруженный виртуальной машиной Java, полностью отображается в адресное пространство. Это означает, что чем больше файлов EAR/JAR вы загружаете в одну JVM, тем выше будет основной объем памяти вашего Java-процесса.

Это также означает, что чем выше ваше пространство Java Heap и PermGen; нижняя память остается для ваших собственных пространств памяти, таких как C-Heap и MMAP Files, что может быть проблемой, если вы развертываете слишком много отдельных приложений (файлы EAR) в один 32-разрядный Java-процесс.

Обратите внимание, что Sun придумала улучшения в JDK 1.6 (Mustang) и изменила поведение, так что центральный каталог JAR файла все еще отображается, но сами записи читаются отдельно; уменьшая потребность в основной памяти.

Я предлагаю вам более подробно рассмотреть ссылку на идентификатор Sun Bug Id ниже для ограничения JDK 1.4/1.5. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6280693