繁体   English   中英

Java OutOfMemory异常:加载zip文件时出现mmap错误

[英]Java OutOfMemory exception: mmap error on loading zip file

我使用JVM参数在生产环境(rhel 5.2 x64,oracle jre 1.7_05,tomcat 7.0.28)上运行我的应用程序:

-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

在耗尽交换空间或耗尽允许的内存映射等资源之前,我已经看到了这些错误。 看看sudo cat /proc/$PID/maps | wc -l sudo cat /proc/$PID/maps | wc -lcat /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以及这是一个相对较新的收集器,不应该改变你的结果。

不知道Java 1.7中有什么变化,我记得从Java 1.6我们使用Xms选项,如下所示。

  -Xms=512m -Xmx=512m

尝试这些选项

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

这将在应用程序根目录中生成转储文件。 稍后您可以使用HP Jmeter进行分析。 这将简要介绍8Gig内存的情况。 您可以在此处查看HP JMeter手册。

还明智地选择了你的Xrunhprof选项。 我提到的上述选项会产生巨大的转储文件。 从手册中您可以找到合适的选项。

原始博客文章的一些段落,这解释了java jar / zip如何工作:

在Java JDK ZipFile的本机调用(ZipFile.open(本机方法))期间触发OOM错误以加载我们的应用程序EAR文件。 此本机JVM操作需要适当的本机内存和虚拟地址空间才能执行其加载操作。 此时的结论是我们的Java VM 1.5在部署时耗尽了本机内存/虚拟地址空间。

Sun Java VM本机内存和MMAP文件

使用JDK 1.4 / 1.5时,Java VM加载的任何JAR / ZIP文件都会完全映射到地址空间。 这意味着您加载到单个JVM的EAR / JAR文件越多,Java进程的本机内存占用量就越高。

这也意味着Java Heap和PermGen空间越高; 较低的内存留给您的本机内存空间,如C-Heap和MMAP文件,如果您将太多单独的应用程序(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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM