как улучшить код Java на основе этой статистики?

У меня есть веб-приложение, которое преобразует некоторые файлы PCL в PDF, запуская задачу планировщика каждые 10 секунд. Каждый раз требуется макс. 20 файлов ПК из каталога и конвертировать их в pdf.

Первые несколько задач выполняются хорошо, но постепенно они становятся медленнее, и внезапно появляется сообщение об ошибке GC overhead limit exceeded.

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

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

Я использую byte в одном классе в трех методах: byte[] buf = new byte[1024];

 public void initBuf() {
        if (buf != null) {
            for (int i = 0; i < buf.length; i++) {
                buf[i] = (byte) 0x00;
            }

            pdf_y = PageSize.A4.getHeight();
        }
    }

public void appendBuf(char ch) {

        if (ch == '\n') {
            processChunk();
            drawChunks();
            pdf_newline();
        } else if (ch != '\r') {
            buf[buf_index++] = (byte) (0xff & ch);
        }
    }

    public void resetBuf() {
        for (int i = buf_index; i >= 0; i--) {
            buf[i] = (byte) 0x00;
        }

        buf_index = 0;
    }

Где бы вы посоветовали мне искать? Как я могу действительно определить, какой из моего кода делает это вредно?

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

заранее спасибо


person Cristian Boariu    schedule 19.04.2011    source источник
comment
что ты пробовал? (возможно, вы могли бы увидеть некоторые улучшения, агрессивно обнуляя слоняющиеся массивы больших байтов, которые вы запрашиваете, когда закончите с ними)   -  person Joseph Weissman    schedule 19.04.2011


Ответы (2)


На снимке экрана вашего профилировщика показано 3,3 миллиона экземпляров java.lang.Byte, а не byte[]. Я бы поискал в другом месте использование Byte (возможно, включая экземпляры, которые были автоматически упакованы из byte, чтобы вставить их в коллекцию).

Мое первое подозрение заключается в том, что какая-то другая часть вашего кода добавляет к карте экземпляры Byte или byte (либо в качестве ключа, либо в качестве значения) и не может удалить их при они больше не нужны. Но это всего лишь предположение, основанное на нескольких моих собственных утечках памяти.

person AaronD    schedule 19.04.2011
comment
По крайней мере, если бы я мог найти в виртуальной машине класс, который делает это с байтами... - person Cristian Boariu; 20.04.2011
comment
Также обратите внимание, что у вас есть 301 экземпляр Byte[], в совокупности потребляющих 212 МБ памяти. Вы можете искать в своем коде ссылки на Byte[] или отслеживать ссылки на эти массивы Byte[] в VisualVM. - person AaronD; 20.04.2011

Ознакомьтесь с руководствами VisualVM по работе с дампом кучи: вот Oracle.

Вы также можете искать ссылки на NetBeans, поскольку компонент тот же, например. Как вы находите утечки памяти с помощью профилировщика Netbeans?< /а>

Вам нужно знать, кто создает или сохраняет ссылки на эти Byte[] и Byte. Один из планов атаки состоит в том, чтобы изучить отдельные экземпляры Byte[] ("Просмотр экземпляров") и просмотреть их ссылки. Опция «Ближайший корень GC» покажет один путь объектов, который сохраняет затяжной Byte[].

person Michael Brewer-Davis    schedule 19.04.2011
comment
Проблема в том, что если я нажимаю на экземпляр byte[], я вижу ссылки с правой стороны, но я вижу только [] (тип массива) и o (тип объекта) и нет корневой стрелки GC для моих переменных... - person Cristian Boariu; 20.04.2011
comment
Показать ближайший корень GC — это параметр контекстного меню, вызываемого правой кнопкой мыши. Если нет корня GC, это должно означать, что объект подходит для GC. - person Michael Brewer-Davis; 20.04.2011