Сбой JVM в ZipFile.getNextEntry () - часть BigGridDemo POI - PullRequest
3 голосов
/ 23 августа 2011

У меня есть приложение Java для создания листов Excel. Я делаю это на основе примера BigGridDemo Apache POI для создания Excel (xlsx).

Идея состоит в том, чтобы

  1. создание шаблонной рабочей книги, создание листов и глобальных объектов, таких как стили ячеек, числовые форматы и т. Д.
  2. создать приложение для потоковой передачи данных в текстовом файле
  3. Заменить лист в шаблоне сгенерированными данными

В Linux на третьем шаге JVM падает с этой информацией

# A fatal error has been detected by the Java Runtime Environment:
#  SIGSEGV (0xb) at pc=0x000000307a772c44, pid=11781, tid=1088649568
#
# JRE version: 6.0_24-b07
# Java VM: Java HotSpot(TM) 64-Bit Server VM (19.1-b02 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [libc.so.6+0x72c44]  memcpy+0x34

Файл hs_err_pid имеет это -

C  [libc.so.6+0x72c44]  memcpy+0x34

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  java.util.zip.ZipFile.getNextEntry(JI)J+0
j  java.util.zip.ZipFile.access$400(JI)J+2
j  java.util.zip.ZipFile$2.nextElement()Ljava/util/zip/ZipEntry;+54
j  java.util.zip.ZipFile$2.nextElement()Ljava/lang/Object;+1

Похоже, это происходит, когда книга шаблона читается в виде zip-файла. Это код, который делает это.

ZipFile zip = new ZipFile(zipfile);
ZipOutputStream zos = new ZipOutputStream(out);

Enumeration<ZipEntry> en = (Enumeration<ZipEntry>) zip.entries();
while (en.hasMoreElements()) {
    ZipEntry ze = en.nextElement();
    if(!ze.getName().equals(entry)){
        zos.putNextEntry(new ZipEntry(ze.getName()));
        InputStream is = zip.getInputStream(ze);
        copyStream(is, zos);
        is.close();
    }
}

Как мне избежать этого сбоя?

Ответы [ 2 ]

1 голос
/ 07 февраля 2014

Учитывая тип сбоя, который вы испытываете, кажется, что вы читаете и пишете в один и тот же zip-файл.

Я написал, почему это происходит, в другом ответе , но для вашего случая использования вы должны записать в другой выходной zip-файл при выполнении итерации по входному zip-файлу.

0 голосов
/ 23 августа 2011

JVM будет аварийно завершать работу в linux (возможно, на других платформах), если вы скажете ей использовать 1 ГБ, 2 ГБ и т. Д., А в системе недостаточно доступной памяти. Когда программа в JVM пытается выделить больше памяти, чем параметр max memory, в JVM, что приводит к исключению OutOfMemoryException, и JVM не падает. Я бы проверил и убедился, что в вашей системе нет другой программы, которая потребляет больше памяти, чем вы думаете. Вы также можете проверить дампы кучи, которые выходят из JVM. Когда JVM дает сбой, он записывает отчет, который сообщает вам больше информации о состоянии машины, когда он зависал, например, сколько системной памяти использовалось.

1ГБ - это огромный объем памяти. Моя IDE не работает с таким большим количеством памяти. Вам, вероятно, нужно посмотреть, что вы делаете в jconsole или в профилировщике, и посмотреть, не израсходовали ли вы память самостоятельно. Я знаю, что POI может сжечь много памяти, но вам нужно найти способ вернуть его обратно.

...