Pergunta

I'm facing a problem I can't seems to fix and I need your help.

I'm generating a list of PDF that I write to the hard drive and everything works fine for a small amount of files, but when I start to generate more files (via a for loop), the creations stops and the others PDF files arent created.

I'm using Play Framework with the PDF module, that rely on ITextRenderer to generate the PDF.

I localized the problem (well, I believe it's here) by adding outputs to see where it stops, and the problem is when I call .createPDF(os);.

At first, I was able to only create 16 files and after that, it would stops, but I created a Singleton that creates the renderer in the Class instance and re-use the same instance (in order to avoid adding the fonts and settings everytime) and I went to 61 files created, but no more.

I though about a memory leak that blocks the process, but can't see where nor how to find it correctly.

Here's my part of the code :

List models; // I got a list of MyModel from a db query, this MyModel contains a path to a file

List<InputStream> files = new ArrayList<InputStream>();

for (MyModel model : models) {
    if (!model.getFile().exists()) {
        model.generatePdf();
    }
    files.add(new FileInputStream(model.getFile()));
}

// The generatePDF :

public void generatePdf() {
    byte[] bytes = PDF.toBytes(views.html.invoices.pdf.invoice.render(this, due));


    FileOutputStream output;
    try {
        File file = getFile();
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }

        if (file.exists()) {
            file.delete();
        }

        output = new FileOutputStream(file);
        BufferedOutputStream bos = new BufferedOutputStream(output);
        bos.write(bytes);

        bos.flush();
        bos.close();

        output.flush();
        output.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

As you can see, I do my best to avoid memory leaks but this isn't enough.

In order to locate the problem, I replaced PDF.toBytes and all subsequent calls from that class to a copy/paste version inside my class, and added outputs. That's how I found that the thread hangs at createPDF, line

Update 1: I have two (indentical) PlayFramework applications running with those parameters :

-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m

I tried to stop one instance and re-execute the PDF generation, but it didn't impact the number of file generated, it stops at the same amount of files. I also tried to update the allocated memories :

 -Xms1536m -Xmx1536m -XX:PermSize=1024m -XX:MaxPermSize=1024m

No changes at all neither.

For information, the server has 16 Gb of RAM.

cat /proc/cpuinfo :

model name  : Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz
cpu MHz     : 3101.000
cpu cores   : 4
cache size  : 6144 KB

Hope it'll helps.

Foi útil?

Solução

Well I'm really surprised the bug has absolutely nothing related to memory, memory leaks or available memory left.

I'm astonished.

It's related to an image that was loaded via an url, in the same server (local), that was taking to long to load. Removing that image fixed the issue.

I will make a base64 encoded image and it should fix the issue.

I still can't believe it!

Outras dicas

The module is developed by Jörg Viola, I think it's safe to assume everything is fine on this side. From the IText library, I also believe it's safe to assume that everything is safe.

The bottleneck, as you guessed, was from your code. The interesting part was that it's wasn't some memory not properly managed, but from a network request that was making the PDF rendering slower and slower everytime, until it would ultimately fails.

It's nice you finally make it work.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top