11

我使用 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

4

4 回答 4

4

I have seen these error before when running out of resources such as running out of swap space or running out of allowed memory mapping. Have a look at sudo cat /proc/$PID/maps | wc -l compared with cat /proc/sys/vm/max_map_count

See comments below.


I also suggested ....

You appear to have run into a bug with YourKit. What version are you using?

I would cut down most of your options as they either are the default and don't do anything or could be complicating matters.

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

I would try dropping -XX:+UseG1GC as well as this is a relatively new collector and shouldn't change your results.

于 2012-10-10T08:50:41.970 回答
0

试试这些选项

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

这将在应用程序根目录中生成一个转储文件。稍后您可以使用HP Jmeter进行分析。这将为您的 8G 内存所发生的情况提供快照。您可以在此处查看 HP JMeter 手册。

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

于 2012-10-10T08:59:28.993 回答
0

不知道 Java 1.7 发生了什么变化,我记得从 Java 1.6 开始,我们使用 Xms 选项,如下所示。

  -Xms=512m -Xmx=512m
于 2012-10-10T08:45:36.890 回答
0

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

OOM 错误是在从 Java JDK ZipFile 进行本机调用 (ZipFile.open(Native Method)) 以加载我们的应用程序 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

于 2013-04-13T02:49:49.867 回答