Недостаточно памяти в моем коде - PullRequest
2 голосов
/ 13 декабря 2010

Я выполняю код в течение долгих часов в рамках стресс-теста на базе данных Oracle и использую версию Java 1.4.2.Короче говоря, я делаю:

while(true)
{
    Allocating some memory as a blob
    byte[] data = new byte[1000];
    stmt = fConnection.prepareStatement(query); // [compiling an insert query which uses the above blob]
    stmt.execute();  // I insert this blob-row in the database. 
stmt.close();

}

Теперь я хочу запустить этот тест в течение 8-10 часов.Однако, видимо, вставив около 15 миллионов записей, я нажал java.lang.OutOfMemoryError

Я запускаю это с -Xms512m -Xmx2g.Я пытался использовать более высокие значения, но у меня не так много оборудования, и я не думаю, что это требование:

    java -Xms512m -Xmx4g -jar XX.jar
    Invalid maximum heap size: -Xmx4g
    The specified size exceeds the maximum representable size.
    Could not create the Java virtual machine.
    java -Xms2g -Xmx3g -jar XX.jar
    Error occurred during initialization of VM
    Could not reserve enough space for object heap
    Could not create the Java virtual machine.

Я запускаю это как многопоточную программу.Таким образом, arnd 10 потоков выполняет вставки.

Есть ли способ, которым я могу обойти эту программу, возможно, без взлома.Я имею в виду, что если я решу запустить это в течение 15-20 часов вместо 8-10 часов.

РЕДАКТИРОВАТЬ: добавлен stmt.close, так как я уже использую это в своем коде.некоторые изменения, основанные на комментариях

Спасибо

PS: извините, не могу опубликовать код из-за NDA

Ответы [ 6 ]

6 голосов
/ 13 декабря 2010

В принципе, я думаю, что вы лаете не на то дерево:

  • JVM / GC удастся освободить недоступные объекты, независимо от того, как быстро вы их выделите. Если вы работаете с классическим неконкурентным GC, то JVM просто перестанет делать другие вещи, пока GC не освободит память. Если вы сконфигурировали JVM для использования одновременного GC, он попытается запустить GC и обычные рабочие потоки одновременно ... и вернется к режиму «все остановить и собрать», если он не сможет продолжать работу.

  • Если вам не хватает памяти, это происходит потому, что что-то в вашем приложении (или в библиотеках / драйверах) использует утечку памяти. Другими словами, что-то делает объекты доступными, даже если ваше приложение больше не нуждается в них.

Как отмечалось в комментариях, вам необходимо решить эту проблему методично, используя профилировщик памяти / дамп кучи. Случайное изменение вещей или обвинение в GC вряд ли решит проблему.

(Когда вы говорите "... я все время использовал stmt.close ()" , я предполагаю, что это означает, что ваш код выглядит примерно так:

    PreparedStatement stmt = ... 
    try {
        stmt.execute();
        // ...
    } finally {
        stmt.close();
    }

Если вы не наберете close вызов в finally, возможно, вы НЕ звоните close каждый раз. В частности, если какое-либо исключение возникает во время вызова execute или между ним и вызовом close, возможно, что close не будет вызвано ... и это приведет к утечке.)

1 голос
/ 12 мая 2013

Это выполнение вызывает из OracleConnection NativeMemory.Для работы с NIO oracle jdbc ребята решили использовать родную часть памяти.Скорее всего, после слишком частого выполнения этого запроса ваше приложение будет выгружено.Чтобы избавиться от этого, вы можете увеличить размер кэша jdbc или перезапустить приложение через промежутки времени

1 голос
/ 13 декабря 2010

Если в вашем коде или библиотеке есть утечка, Memory Analyzer (MAT) - это бесплатное приложение на основе Eclipse для изучения файлов дампа памяти Java.Инструкции включают в себя, как заставить его сбросить файл дампа для вас.http://www.eclipse.org/mat/

1 голос
/ 13 декабря 2010

Я думаю, вам следует добавить

stmt.close();

, чтобы память, выделенная для подготовленного состояния, была освобождена.

0 голосов
/ 13 декабря 2010

Редактировать: кажется, что это может быть известная проблема с драйвером Oracle: http://www.theserverside.com/discussions/thread.tss?thread_id=10218


Просто вкратце, я знаю, что вы делаете простой JDBC здесь, но если выЕсли у вас есть какие-либо энхансеры (AspectJ, Hibernate, JPA), есть (незначительный) шанс утечки в Пермском крае, установите -XX:MaxPermGen=256m просто для безопасности

Также профилировщик памяти jvisualvm и jprofiler (использовать пробную версию) будет точно указать его

0 голосов
/ 13 декабря 2010
java -Xms2g -Xmx3 -jar XX.jar
Error occurred during initialization of VM
Incompatible minimum and maximum heap sizes specified

Попробуйте

java -Xms2g -Xmx3g -jar XX.jar

Сколько памяти у вас на коробке? Вы используете 32-битную или 64-битную JVM?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...