Hi all - running into a frustrating problem:
As part of a commercial application I work on, we have a module which
generates PDFs for users to survey people.
We build these survey PDFs as a large document containing information
about the person being surveyed and also barcodes which correspond to
each survey answer.
Recently, as this module has been getting more use, we noticed it has
begun throwing OutOfMemoryErrors, but of course only with very large
documents.
At first I suspected it was the fact that we were using one PdfPTable
per document, which I fixed after reading this helpful piece in the
docs:
http://itextdocs.lowagie.com/tutorial/objects/tables/pdfptable/index.php#memory
However, after doing more extensive testing - I noticed we were still
running out of memory. I added more extensive logging and stumbled
upon something disturbing: the memory was not slowly creeping up while
the PDF was being generated and the document was having tables/cells
added to it. Rather, when document.close() is called, the memory
spikes tremendously, consistently consuming over a gig of heap space
for a 2000 person survey PDF!!
Here are some more details for a specific use case:
2000 person survey - each person surveyed has 15 corresponding
barcodes. This comes out to 30,000 barcodes total in the document.
Once rendered, the entire document is only about 10MB. It is
especially concerning to me that generating a 10MB PDF could use 1.5GB
of Java heap memory!
Here is how we generate our barcodes and add them to the document:
public static Phrase barcode128(PdfContentByte pcb, String code,
String altText, int textAlignment, Font font, int baseline, float
heightMultiplier) {
Barcode128 barcode = new Barcode128();
barcode.setCode(code);
barcode.setFont(font.getCalculatedBaseFont(false));
barcode.setAltText(altText);
barcode.setBaseline(baseline);
barcode.setTextAlignment(textAlignment);
float height = barcode.getBarHeight();
barcode.setBarHeight(height * heightMultiplier);
Image barcodeImage = barcode.createImageWithBarcode(pcb, null,
null);
return new Phrase(new Chunk(barcodeImage, 0, 0));
}
That phrase is then added to a table cell, and that table is then
added to a master table which is "fragmented" every 20 persons.
I have added logging to the application and watching the logging the
heap never grows in size during the actual rendering and generation of
the PDF (staying constant at about 450MB for the entire application).
However, once I call Document.close the heap memory spikes very
quickly anywhere between 1.5 and 2.0GB which seems extremely excessive
to me.
My guess is iText is "holding" onto these barcode images and only
rendering them when the document closes - in bulk - and without
flushing. This seems to imply that each barcode image being generated
is around 50k of heap memory, and that iText is holding onto every
single one of those images.
Is anyone doing something like this, and if so, how are you managing
your barcode images? Has anyone had any luck with using a Barcode128
font instead of using the native iText Barcode128 generation? Does
anyone see any glaring holes in our methods?
Thanks in advance for ANY help you can provide...
Cheers,
-Zach Bailey
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://www.1t3xt.com/docs/book.php