[英]OutOfMemory error but application continues in java
I have faced OutOfMemory error in my application. 我在应用程序中遇到了OutOfMemory错误。 But the thing is my application keeps on running though it has thrown OutOfMemeory.
但问题是,尽管我的应用程序抛出了OutOfMemeory,但仍保持运行状态。 After some two minutes later, JVM has quit and pid file got genearted throwing
两分钟后,JVM已退出,并且pid文件被普遍抛出
java.lang.OutOfMemoryError: requested 746 bytes for jbyte in
/BUILD_AREA/jdk6_21/hotspot/src/share/vm/prims/jni.cpp. Out of swap space?.
1) Is it possible for JVM to continue running even after throwing OutOfMemory error ? 1)即使抛出OutOfMemory错误,JVM是否仍可以继续运行? 2)Also can you give me some direction to investigate on this further?
2)您还可以给我一些指导,以便对此进行进一步调查吗?
I am pasting the excerpt from log to get a better understanding. 我粘贴了日志摘录,以更好地理解。
1) There are two out of memory errors. 1)有两个内存不足错误。 One at 2011.12.09 16.04.09:446 and another at 2011.12.09 16.04.40:818
一个在2011.12.09 16.04.09:446,另一个在2011.12.09 16.04.40:818
2011.12.09 16.04.09:446 664849490 WARNING {HTTP@9800-168}RULEZ runtime exception [transcoding]
java.lang.OutOfMemoryError
at java.util.zip.Inflater.inflateBytes(Native Method)
at java.util.zip.Inflater.inflate(Inflater.java:238)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:135)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:105)
at java.util.jar.JarVerifier$VerifierStream.read(JarVerifier.java:428)
at java.io.FilterInputStream.read(FilterInputStream.java:66)
at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:75)
at javax.mail.Session.loadProvidersFromStream(Session.java:932)
at javax.mail.Session.access$000(Session.java:174)
at javax.mail.Session$1.load(Session.java:870)
at javax.mail.Session.loadResource(Session.java:1084)
at javax.mail.Session.loadProviders(Session.java:889)
at javax.mail.Session.<init>(Session.java:210)
at javax.mail.Session.getInstance(Session.java:249)
.
.
.[Application continues here]
.
.
.
2011.12.09 16.04.40:818 664882092 WARNING {HTTP@9800-168}RULEZ runtime exception [transcoding]
java.lang.OutOfMemoryError
at java.util.zip.Inflater.inflateBytes(Native Method)
at java.util.zip.Inflater.inflate(Inflater.java:238)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:135)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:105)
at java.util.jar.JarVerifier$VerifierStream.read(JarVerifier.java:428)
at java.io.FilterInputStream.read(FilterInputStream.java:66)
at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:75)
at javax.mail.Session.loadProvidersFromStream(Session.java:932)
at javax.mail.Session.access$000(Session.java:174)
at javax.mail.Session$1.load(Session.java:870)
at javax.mail.Session.loadResource(Session.java:1084)
at javax.mail.Session.loadProviders(Session.java:889)
at javax.mail.Session.<init>(Session.java:210)
at javax.mail.Session.getInstance(Session.java:249)
.
.
.
.
.
2) At Dec 9 16:07,JVM quits and created pid file as below. 2)在12月9日16:07,JVM退出并创建pid文件,如下所示。 So, there is ~2 minutes gap between OutOFMemory error log statement and for jvm to quit and create pid file.
因此,OutOFMemory错误日志语句与jvm退出并创建pid文件之间大约有2分钟的间隔。
$ls
-rw-rw-r-- 1 ins ins 156076 Dec 9 16:07 hs_err_pid29157.log
-rw------- 1 ins ins 3055525888 Dec 9 16:07 core.29157
#
# A fatal error has been detected by the Java Runtime Environment:
#
# java.lang.OutOfMemoryError: requested 746 bytes for jbyte in /BUILD_AREA/jdk6_21/hotspot/src/share/vm/prims/jni.cpp. Out of swap space?
#
# Internal Error (allocation.inline.hpp:39), pid=21129, tid=667401120
# Error: jbyte in /BUILD_AREA/jdk6_21/hotspot/src/share/vm/prims/jni.cpp
#
# JRE version: 6.0_21-b06
# Java VM: Java HotSpot(TM) Server VM (17.0-b16 mixed mode linux-x86 )
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
--------------- T H R E A D ---------------
Current thread (0x2f929000): JavaThread "DRIVER:adapter:12:7" [_thread_in_vm, id=21834, stack(0x27c5b000,0x27c7c000)]
Stack: [0x27c5b000,0x27c7c000], sp=0x27c7a874, free space=7e27c7c000k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x6a9262]
V [libjvm.so+0x2b277f]
V [libjvm.so+0x3c0b0f]
C [libocijdbc10.so+0x108ff]
C [libocijdbc10.so+0x11788] Java_oracle_jdbc_driver_T2CConnection_lobGetLength+0x30
J oracle.jdbc.driver.T2CConnection.lobGetLength(J[BI)J
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J oracle.jdbc.driver.T2CConnection.lobGetLength(J[BI)J
J oracle.jdbc.driver.T2CConnection.length(Loracle/sql/BLOB;)J
J com.fh.common.database.ReadConnectionImpl.getByteArray(Ljava/lang/String;Ljava/sql/ResultSet;I)[B
J com.fh.common.database.ReadConnectionWrapper.getByteArray(Ljava/lang/String;Ljava/sql/ResultSet;I)[B
J com.fh.mr.storage.MultiJDBCStorage.fillInitiator(Lcom/fh/common/database/ReadConnection;Ljava/lang/String;Ljava/sql/ResultSet;Lcom/fh/mr/router/TransactionResponder;)Lcom/fh/mr/router/TransactionInitiator;
J com.fh.mr.storage.MultiJDBCStorage.addInitiators(Lcom/fh/mr/router/TransactionResponder;Ljava/util/Collection;)V
J com.fh.mr.storage.CacheStorage.getResponderByTransactionID(Ljava/lang/String;)Lcom/fh/mr/router/TransactionResponder;
j com.fh.mr.router.RoutingEngine.getResponderByTransactionID(Ljava/lang/String;)Lcom/fh/mr/router/TransactionResponder;+5
j com.fh.mr.router.RoutingEngine.scheduleStatusResend(Ljava/lang/String;)Z+53
j com.fh.mr.router.RoutingEngine.scheduleResend(Lcom/fh/mr/message/Message;I)Z+68
j com.fh.mr.drivers.Driver.getMessage(Ljava/lang/Object;)Lcom/fh/mr/message/Message;+260
J com.fh.mr.drivers.Driver$QueueWorker.run()V
j com.fh.common.threadpool.ThreadControl.run()V+47
j com.fh.common.threadpool.ThreadPool$PoolThread.run()V+467
v ~StubRoutines::call_stub
Thanks,
Vijay
Is it possible for JVM to continue running even after throwing OutOfMemory error ?
即使抛出OutOfMemory错误,JVM是否仍可以继续运行?
Sure. 当然。 The OutOfMemory error can be caught, and even if not, it just kills the current thread.
可以捕获OutOfMemory错误,即使没有,也只会杀死当前线程。 Any other threads can continue to run.
任何其他线程都可以继续运行。
Also can you give me some direction to investigate on this further?
您还可以给我一些指导,以便对此进行进一步调查吗?
According to the stacktrace, your program ran out of memory while trying to open some jar file. 根据stacktrace,您的程序试图打开一些jar文件时内存不足。 However, that does not necessary need to be the culprit (ie the task that ate up too much memory).
但是,这不一定是罪魁祸首(即占用过多内存的任务)。 You need to find out what part of your program uses too much memory, and then either reduce that somehow, or allocate more memory to the JVM.
您需要找出程序的哪个部分使用了过多的内存,然后以某种方式减少内存使用量,或为JVM分配更多的内存。
You should also watch for memory leaks which sometimes happen for long-running processes, especially when some classes get reloaded, for example. 您还应该注意长时间运行的进程有时会发生的内存泄漏,例如,某些类重新加载时。 If you find that you have a server process that slowly grows in size over time, a quick fix (easier than changing code) could be to restart it once in a while.
如果发现服务器进程的大小随着时间的推移缓慢增长,则快速解决方案(比更改代码更容易)可能是不时地重新启动它。
At Dec 9 16:07,JVM quits and created pid file as below.
在12月9日16:07,JVM退出并创建pid文件,如下所示。
The JVM crashed there with an internal error. JVM因内部错误而崩溃。 That should not happen.
那不应该发生。 However, this may very well have been caused by operating for two minutes very close to the memory limit.
但是,这很可能是由于在非常接近内存限制的情况下运行了两分钟而引起的。 After an OutOfMemory error, things tend to break.
在发生OutOfMemory错误后,事情往往会中断。 Do you get this crash report more often?
您会更频繁地获得该崩溃报告吗?
1) Is it possible for JVM to continue running even after throwing OutOfMemory error ?
1)即使抛出OutOfMemory错误,JVM是否仍可以继续运行?
Yes, after a fashion, depending on what the application is and what it is doing. 是的,遵循某种方式,取决于应用程序是什么以及正在做什么。
The lifecycle of an OOME is a follows: OOME的生命周期如下:
What happens next depends on how the application deals with the exception. 接下来发生的情况取决于应用程序如何处理异常。
So lets assume that we are "keeping going". 因此,假设我们正在“继续前进”。 Will it work?
能行吗 The answer is that it depends.
答案是,这取决于。
Unfortunately, the application typically can't continue due to the above issues. 不幸的是,由于上述问题,该应用程序通常无法继续运行。 And even when it can continue, it often will fail again fairly shortly.
即使它可以继续,它通常也会很快再次失效。 The root cause of the OOME in a long running application is typically a memory leak, and the best short-term cure is to restart the JVM and the application.
在长时间运行的应用程序中,OOME的根本原因通常是内存泄漏,最好的短期解决方法是重新启动JVM和应用程序。
2)Also can you give me some direction to investigate on this further?
2)您还可以给我一些指导,以便对此进行进一步调查吗?
If you have a memory leak, you probably can't deduce anything by looking at what was happening when the OOME was thrown. 如果存在内存泄漏,则可能无法通过查看抛出OOME时发生的情况来推断出任何东西。 The allocation that failed is unlikely to be the real cause of the problem.
分配失败很可能不是问题的真正原因。
So my advice would be to start by checking the application for memory leaks. 因此,我的建议是从检查应用程序内存泄漏开始。
As others said OutOfMemoryError is an Error that can be caught and handled. 正如其他人所说, OutOfMemoryError是可以捕获和处理的错误。
To investigate the error further you will need to use VisualVM either to 要进一步调查错误,您将需要使用VisualVM来执行以下操作:
To generate the heap dump start your application with -XX:+HeapDumpOnOutOfMemoryError
parameter, wait for the OutOfMemoryError, grab the heap dump and feed it to VisualVM. 要生成堆转储,请使用
-XX:+HeapDumpOnOutOfMemoryError
参数启动应用程序,等待OutOfMemoryError,获取堆转储并将其提供给VisualVM。
Googling for VisualVM and OutOfMemoryError will give you all kind of usage scenarios. 谷歌搜索VisualVM和OutOfMemoryError将为您提供各种使用方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.