как да подобря Java кода въз основа на тази статистика?

Имам уеб приложение, което преобразува някои PCL файлове в PDF, като изпълнява задача за планиране на всеки 10 секунди. Всеки път отнема макс. 20 компютърни файла от директория и ги конвертирайте в pdf.

Първите няколко задачи се изпълняват добре, но стъпка по стъпка стават по-бавни и изведнъж се извежда съобщение за грешка GC overhead limit exceeded.

Опитах се да анализирам това изтичане на памет с VisualVM и ето малко изход от heapdump:въведете описание на изображението тук

Странно е, че се показва такъв брой байтове екземпляри (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
Поне ако мога да намеря във VM кой е класът, който прави тези неща с байтове... - person Cristian Boariu; 20.04.2011
comment
Също така имайте предвид, че имате 301 екземпляра на Byte[], които общо консумират 212 MB памет. Можете да търсите в кода си за препратки към Byte[] или да проследите обратно чрез препратки към тези масиви Byte[] във VisualVM. - person AaronD; 20.04.2011

Разгледайте ръководствата на VisualVM за работа с дъмпове на купчина: ето го на Oracle.

Можете също така да потърсите препратки към NetBeans, тъй като компонентът е същият, напр. Как намирате изтичане на памет с помощта на Netbeans Profiler?

Трябва да знаете кой създава или запазва препратки към тези Byte[]s и Bytes. Един план за атака би бил да се изследват отделни 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