2011-12-16 4 views
0

Я столкнулся с ошибкой OutOfMemory в своем приложении. Но дело в том, что мое приложение продолжает работать, хотя оно выбрасывает OutOfMemeory. После того, как около двух минут, JVM прекращал и PID-файл получил genearted метанияОшибка OutOfMemory, но приложение продолжается в java

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) Можно ли для JVM продолжать работать даже после того, как бросать OutOfMemory ошибку? 2) Также вы можете дать мне какое-то направление, чтобы исследовать это дальше?

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

1) Есть две ошибки в памяти. Один на 2011.12.09 16.04.09: 446, а другой на 2011.12.09 16.04.40: 818

2011.12.09 16.04.09:446 664849490 WARNING {[email protected]}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 {[email protected]}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) В 9 Дек 16: 07 завершает работу виртуальной машины Java и создал Pid файл, как показано ниже. Таким образом, между оператором журнала ошибок OutOFMemory существует ~ 2 минуты и для jvm для выхода и создания файла pid.

$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 

ответ

3

Возможно ли для JVM продолжать работать даже после того, как бросать OutOfMemory ошибку?

Несомненно. Ошибка OutOfMemory может быть поймана, и даже если нет, она просто убивает текущий поток. Любые другие потоки могут продолжать работать.

Также вы можете дать мне какое-то направление для изучения этого вопроса дальше?

Согласно stacktrace, ваша программа закончилась нехваткой памяти при попытке открыть файл jar. Однако это не обязательно должно быть виновником (т. Е. Задачей, которая поглотила слишком много памяти). Вам нужно выяснить, какая часть вашей программы использует слишком много памяти, а затем либо как-то уменьшить, либо выделить больше памяти для JVM.

Вы также должны следить за утечками памяти, которые иногда происходят для длительных процессов, особенно когда некоторые классы загружаются, например. Если вы обнаружите, что у вас есть серверный процесс, который медленно растет со временем, быстрое исправление (проще, чем изменение кода) может состоять в том, чтобы перезапустить его время от времени.

С 9 декабря 16: 07, JVM завершает работу и создает файл pid, как показано ниже.

JVM был разбит с внутренней ошибкой. Этого не должно быть. Однако это вполне может быть вызвано работой в течение двух минут, очень близкой к пределу памяти. После ошибки OutOfMemory все имеет тенденцию ломаться. Вы чаще получаете этот отчет об аварии?

+0

1-й ООМ происходит при чтении почты, не открывая банку – bestsss

+0

не очень часто. но это произошло дважды на нашем производственном сервере ... ошибка OutOfMemeory в файле журнала показывает, что это произошло, когда наше приложение пытается разобрать огромное содержимое SOAP ... но когда я вижу файл сбоя, он выбрал OutOfMemory, когда драйвер Oracle OCI пытается читать blob из db..so, на котором я должен начать копать дальше..SAP-анализ или чтение DB blob ???? – vijayashankard

2

1) Возможно ли, что JVM продолжит работу даже после выброса ошибки OutOfMemory?

Да, после моды, в зависимости от того, что такое приложение и что он делает.

Жизненный цикл из OOME является следующим:

  • Приложение пытается выделить память (новый объект или массив, новый стек нити, буфер без кучи, etcera), и считает, что он не может.
  • (Для нормального распределения кучи) GC работает ... и не восстанавливает достаточное количество памяти.
  • Исключение выбрано в потоке, который попытался выделить память.

Что будет дальше, зависит от того, как приложение относится к исключению.

  • Если приложение ловит его и выручает, то есть оно. То же самое, если OOME был брошен на «главную» нить, и приложение не поймать его.
  • Если приложение поймает его и пытается возобновить работу ... см. Ниже.
  • Если приложение не улавливает его, а поток НЕ является основным потоком, тогда поток умирает, но приложение продолжает работать.

Так что давайте предположим, что мы «продолжаем». Это будет работать? Ответ в том, что это зависит.

  • Может ли приложение обнаружить, что нить умерла и воссоздает замену?
  • Каково было приложение в середине выполнения, когда OOME был брошен?
  • Был ли он посередине обновления ключевой структуры данных?
  • Развертывание стека вызвало достаточное количество объектов, чтобы получить право на сбор мусора, чтобы приложение могло добиться прогресса?
  • Будет ли приложение просто повторять расчет, который он сделал до этого, в результате чего появился OOME?

К сожалению, приложение, как правило, не может быть продолжено из-за вышеуказанных проблем. И даже когда это может продолжаться, оно часто снова будет неудачно в ближайшее время. Основная причина OOME в приложениях с длительным сроком службы - это, как правило, утечка памяти, и лучшим краткосрочным решением является перезапуск JVM и приложения.

2) Также вы можете дать мне какое-то направление для изучения этого вопроса?

Если у вас есть утечка памяти, вы, вероятно, ничего не можете вывести, посмотрев, что происходит, когда OOME был брошен. Выделение, которое потерпело неудачу, вряд ли станет реальной причиной проблемы.

Так что мой совет должен был бы начать, проверив приложение на утечку памяти.

1

Как было сказано, OutOfMemoryError - ошибка, которую можно поймать и обработать.

Исследовать ошибку в дальнейшем вам нужно будет использовать VisualVM либо к

  • взгляд на потребление памяти на реальном приложении
  • просмотра дампа кучи генерируется Java.

Для генерации дампа кучи запустить приложение с параметром -XX:+HeapDumpOnOutOfMemoryError, ждать OutOfMemoryError, возьмите дамп кучи и кормить его VisualVM.

Googling для VisualVM и OutOfMemoryError предоставит вам все виды сценариев использования.

Смежные вопросы