Hello all - 

I've been using iText for years now but I've recently been having real
difficulties with it.

For years we've been using JBoss as our web server and iText as a PDF report
generator and I've been quite happy with it.

We recently upgraded to Java 1.5 and JBoss 4 and now I'm having memory
issues.

I believe I've tracked it down to iText and more specifically, Images used
in iText.

Here's what I'm doing:

1. I build a report using iText.
2. I build chart (which is a java BuffereredImage) that's built on the fly
and is stored in memory using JFreeChart (http://www.jfree.org/jfreechart/)
3. I put the chart in a PdfPCell which is in a PdfPTable

I carefully watch the memory as the PDFs are being generated, and I can
clearly tell that the images are not being garbage collected.

If I run the reports without images, they are perfect.  All the memory that
was taken while running the report is restored.  However, when run with the
images, memory that is claimed while generating the report is not released
when finished.  Depending on the size of the report, this can be quite a
large amount of memory.  After a few days, the servers run out of memory.

Here's a memory profile while running the reports without images:
Start:  ~140k   Peak usage while running:       175k            After:  140k

With images:
Start:  ~140k   Peak usage while running:       190k            After:  155k

This is adversely affecting my production environment.  Servers are becoming
unresponsive while users are online, and they then require a reboot.
Sometimes this is in the middle of the day which is really disruptive.

This issue occurs with both older versions of iText and the latest...

Here's my code below:

public class ActivityReport
{
    private int fontSize = 10;
    Color border;
    Font font1;
    Font font2;
    Paragraph newLine;
    Document document;
    PdfWriter writer;
    PdfContentByte cb;
    ColumnText ct;
    ByteArrayOutputStream baos;
    
    
    
    public ActivityReport ( HttpServletResponse response )
    {
        try
        {
            
            document = new Document();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            writer = PdfWriter.getInstance(document, baos);

        
            /* create the header and add it to the document */
            Phrase ph = new Phrase("Activity Report2",
                new Font(Font.HELVETICA, 12, Font.NORMAL, new Color(0, 0,
0)));
            HeaderFooter header = new HeaderFooter(ph, false);
            header.setAlignment(header.ALIGN_CENTER);
            document.setHeader(header);

            /* create the footer and add it to the document */
            Phrase before = new Phrase("Page ", new Font(Font.HELVETICA, 8,
Font.NORMAL, new Color(0, 0, 0)));
            Phrase after = new Phrase(".  Copyright 2005, Promantek, Inc.",
new Font(Font.HELVETICA, 8, Font.NORMAL, new Color(0, 0, 0)));
            HeaderFooter footer = new HeaderFooter(before, after);
            footer.setAlignment(header.ALIGN_CENTER);
            document.setFooter(footer);
            document.open();
            /**
             * now let's add the header
             */
            
            Table top = new Table(3);
            top.setWidth(100f);
            top.setBorderWidth(0);
            top.setDefaultCellBorderWidth(0);
            top.setWidths(new int[]{15,50,35}); 

            document.add(top);
            
            addOverallChart();
            
            Vector companies =
IncentivatorsServlet.getCompany().getAllCompanies();
            
            addCompanies( companies );
            
            document.add( getFillerTable() );
            
            document.close();
            // write ByteArrayOutputStream to the ServletOutputStream
            response.setContentType("application/pdf");
            response.setContentLength(baos.size());
            ServletOutputStream out = response.getOutputStream();
            baos.writeTo(out);
            out.flush();
        }
        catch(Exception e)
        {
            System.out.println("Error in TrakStarActivityReport :runReport:
" + e);
            e.printStackTrace(System.out);
        }
    }
    
    private void addOverallChart()
    {
        try
        {
                        ...irrelevant code omitted...

                        addDateChart( firstDateStr, logs, "Overall TrakStar
Activity" );
                        
                        addPageToReport( "Overall", "n/a",
                        
        }
        catch( Exception e )
        {
                System.out.println( "Error in
TrakStarActivityReport:addOverallChart: " + e );
        }
    }
    
    private void addCompanies( Vector companies )
    {
        for( int i = 0; i < companies.size(); i++ )
        {
                CompanyDataBean bean = ( CompanyDataBean )
companies.elementAt( i );
                
                try
                {

                        ... irrelevant code omitted...


                        // add the chart of overall activity
                        addDateChart( firstDateStr, logs,
bean.getCompanyName() );
                        
                        addPageToReport( bean.getCompanyName(),
bean.getCompanySignUpDate(),
                }
                catch( Exception e )
                {
                        System.out.println( "Error in
TrakStarActivityReport:addCompanies: " + e );
                }
        }
    }
    
    private void addPageToReport( String organizationName,
                                                          String
renewalDate,
                                                          String
numActiveEmployees,
                                                          String
numScheduledAppraisals,
                                                          String
numUpcomingAppraisals,
                                                          String
numDelinquentAppraisals,
                                                          String
numCompletedAppraisals)
    {
        try
        {
                Table info = new Table(4);
                info.setWidth(100f);
                info.setBorderWidth(0);
                info.setDefaultCellBorderWidth(0);
                info.setWidths(new int[]{25,25,25, 25});
                
                info.addCell(new Paragraph("Organization Name: ",new
Font(Font.HELVETICA, fontSize, Font.NORMAL, new Color(0, 0, 0))));
                info.addCell(new Paragraph(organizationName,new
Font(Font.HELVETICA, fontSize, Font.NORMAL, new Color(0, 0, 0))));

                  ...
 
                document.add(info);
                document.newPage();
        }
        catch( Exception e )
        {
                System.out.println( "Error in TrakStar activity report:
addPageToReport: " + e );
        }
        
    }
    
    private void addDateChart( String firstDateStr, Hashtable values, String
title )
    {
                ... boring chart generation stuff omitteed

        JFreeChart chart = ...// another class generates it.
        
          //add it to the page
        addChartToPage( chart );
    }
    
    
    private void addChartToPage( JFreeChart chart )
    {
        try
        {
            
            PdfPTable imgTable = new PdfPTable(1);
            imgTable.setTotalWidth(100f);
            
            java.awt.Image img = chart.createBufferedImage( 600, 300 );
            Image ixImg = Image.getInstance( img, null );
            PdfPCell imgCell = new PdfPCell ( ixImg );
            imgCell.setBorderWidth( 0 );
            imgCell.setHorizontalAlignment( Cell.ALIGN_CENTER );
            
            imgTable.addCell( imgCell );
            
            
            if(writer.fitsPage(imgTable))
            {
                document.add(imgTable);
            }
            else
            {
                document.newPage();
                document.add(imgTable);
            }
            
            // attempted gc
            ixImg = null;
            img = null;
            chart = null;
            imgTable = null;
            
            document.add(getFillerTable());
        }
        catch (Exception e)
        {
            System.out.println("error in MultiraterOverallPDF:
addChartToLayout: " + e);
        }
    }

    private Table getFillerTable()
    {
        try
        {
            Table filler = new Table(1);
            filler.setWidth(100f);
            filler.setBorderWidth(0);
            filler.setDefaultCellBorderWidth(0);
            Cell fillCell = new Cell("\n");
            fillCell.setBorderWidth(0);
            filler.addCell(fillCell);

            return filler;
        }
        catch (Exception e)
        {
            return null;
        }
    }
    
}


Hopefully this code is readable.

Any feedback/help would be greatly appreciated...even beyond "greatly
appreciated".  It would be fantastic.

Thanks in advance.

David Martin



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://itext.ugent.be/itext-in-action/

Reply via email to