потенциальная утечка памяти с pdfwriter - PullRequest
0 голосов
/ 05 апреля 2019

Я сталкиваюсь с ошибками при сборке мусора: java.lang.OutOfMemoryError: Превышен предел накладных расходов GC, который я пытаюсь устранить.

В журналах я вижу одну потенциальную проблему при создании отчетов в формате PDF.Этот кусок кода не работал над возможно более 2 лет.Проблема начала возникать два дня назад.

Может ли этот фрагмент кода вызвать утечку памяти?Я больше обеспокоен тем, что писатель принимает выходной поток, а он не закрывается.Док закрывается, достаточно ли этого?Этот бит кода работает нормально в течение нескольких лет.

В приведенном ниже коде средство записи очищено, но не закрыто.Это потенциальная утечка памяти?

  public void formatAndStream(OutputStream out) throws Exception {
    // Translate order to something more manageable.
    // Only the reports know which fields have meaning to them, so delegate this.
    List<FormField> ffs = buildFieldOrder();

    /**
     * Note on HeaderFooter and iText's built-in setHeader() setFooter() **
     * These can only contain text and so do not meet all our needs.
     * We must instead manually build a header and upper footer.
     */
    doc = new Document(pageSize);
    doc.addAuthor(I18.N("repfmt.pdfAuthor"));
    doc.addTitle(pdfTitle);
    doc.addCreationDate();
    doc.addProducer();

    // Build our PDF writer Listeners.
    // DocListener is too generic.
    PdfPageEventHelper list = new PdfPageEventHelper() {
        public void onStartPage(PdfWriter writer, Document document) {
            doStartPage(writer, document);
        }

        public void onEndPage(PdfWriter writer, Document document) {
            try {
                prepareForNextPage(document);
            } catch (Exception e) {
                System.err.println("Error preparing for page " + pageNumber);
                e.printStackTrace();
            }
        }
    };

    // Configure our PDF output.
    writer = PdfWriter.getInstance(doc, out);
    createDate = new Date();
    writer.setPageEvent(list);

    /*
    Margins
        Margins when set apply to the NEXT page to be written.
        Ergo, you must set margins for page 1 with prescient knowledge of the first section to be rendered.
        Each margin set thereafter should occur on end page.
        Subsect header renders must occur on begin page.
     */
    currentReport = findNextCareSubsection(ffs, true);
    currentSubsection = createSubsection(currentReport);
    prepareForNextPage(doc);

    // open the doc for writing
    doc.open();

    try {
        // Write the first section (it's special)
        if (currentSubsection != null) {
            currentSubsection.write(doc, docWidth, writer);
        }

        boolean pageBreakNeeded = false;
        // Iterate the elements in order, rendering them to the PDF output.
        for (FormField ff : ffs) {
            currentReport = null;
            currentSubsection = null;
            if (ff instanceof GeneralField) {
                GeneralField gf = (GeneralField)ff;
                switch (gf) {
                    case Pagebreak:
                        pageBreakNeeded = true;
                        break;
                    default:
                        System.err.println("Dropping unsupported GeneralField:  " + gf);
                }
            } else {
                SubsectionRenderer sr = this.createSubsection(ff);
                if (sr != null) {
                    currentReport = ff;
                    currentSubsection = sr;
                    // If we can fit the subsection's first header on this page, add() it.
                    // If we cannot, break the page.
                    // subsequent header paints must happen as part of a margin set/fill operation
                    float height = currentSubsection.getNextPageHeaderHeight(docWidth);
                    if (!pageBreakNeeded && Util.hasAtLeast(doc, writer, height)) {
                        currentSubsection.writeHeader(doc, docWidth);  // first hit is here
                    } else {
                        doc.newPage();
                        pageBreakNeeded = false;
                    }

                    if (pageBreakNeeded) {   // second hit here
                        doc.newPage();
                        pageBreakNeeded = false;
                    }

                    currentSubsection.write(doc, docWidth, writer);
                }
            }
        }
    } catch (Exception t) {
        doc.add(new Paragraph(I18.N("repfmt.errorMsg"), Defaults.FONT_ERROR));
        throw t;
    } finally {
        try {
            writer.flush();
            doc.close();
        } catch (Throwable t) {
           // prevent stream close exceptions from masking real exceptions
           System.err.println(I18.N("repfmt.4") + t);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...