galkahana / HummusJS

Node.js module for high performance creation, modification and parsing of PDF files and streams
http://www.pdfhummus.com
Other
1.14k stars 169 forks source link

resident set(rss) didn't release #259

Open Timehello opened 6 years ago

Timehello commented 6 years ago

Hi, @galkahana ! Hummus is a great tool for operating pdf work ! But resident set(rss) didn't releas after using Hummus. In Koa app, a simple service to modify a pdf file, the rss grow up larger and larger after each visit the service, but the heap total didn't grow, so it is not the code problem, but the something v8 can't gc. Is it the Hummus problem ?

Best wishes Yours

router.get('/pdf', function(ctx){
    var dir = path.resolve(path.resolve(__dirname, './static/pdf'), 'hn_a.pdf')

    // just simply modify an existing pdf file

    var pdfWriter = hummus.createWriterToModify(dir);
    var pageModifier = new hummus.PDFPageModifier(pdfWriter,0);
    pageModifier.startContext().getContext().writeText(
        'Test Text',
        75, 100,
        {font:pdfWriter.getFontForFile(path.resolve(__dirname, './fonts/Arial.ttf')),size:14,colorspace:'gray',color:0x00}
    );

    pageModifier.endContext().writePage();
    pdfWriter.end();

    // ATTENTION HERE !!! here watch the node memory, the rss(resident set ) grow up each I request 'localhost:3000/pdf' and never release even I stop request for a long time
    console.log(process.memoryUsage())

    ctx.body = 'ok'
})
galkahana commented 6 years ago

I have no idea man. Did some mem leak cleanups way back when. also was having my own web services, and it seems fine. maybe this is modification specifics. wanna debug this a bit? try eliminating some of the calls (like writerText). try appending pages instead of using the PDFPageModifier...then we can tell a little more.

OwlyCode commented 5 years ago

Hello ! I encoutered this issue too. When modifying and sending a pdf every 2 seconds it can reach 1gb resident memory in 7 minutes.

This code is enough for me to cause an increase by 6mb of the RSS :

        pageModifier.startContext().getContext();
        // do nothing
        pageModifier.endContext().writePage();
galkahana commented 5 years ago

makes sense. i think i understand the source of the leak. thank you. i will look into correcting this soon.

OwlyCode commented 5 years ago

If that can help you, I ran valgrind against this script :

const hummus = require('hummus');

pdfWriter = hummus.createWriterToModify('test.pdf');

for (let i = 0; i < 30; i++) {
    let pageModifier = new hummus.PDFPageModifier(pdfWriter, 0, true);

    pageModifier.startContext().getContext();

    pageModifier.writePage();
}
pdfWriter.end();

And got those results : https://gist.github.com/OwlyCode/16a60ab83f56d1ed226e4e38f12827fd

galkahana commented 5 years ago

version 1.0.92 should take care of this.

OwlyCode commented 5 years ago

Thank you for the update ! It reduced the leak by approximatively 50%. I'm also trying some changes on my side to see if I can find something.

There seems to be something going on with the way the driver is created in PdfPageModifierDriver.cpp :

==10799== 6,915,073 (960 direct, 6,914,113 indirect) bytes in 30 blocks are definitely lost in loss record 70 of 71
==10799==    at 0x4C29180: operator new(unsigned long) (vg_replace_malloc.c:324)
==10799==    by 0xA11052E: PDFPageModifierDriver::New(v8::FunctionCallbackInfo<v8::Value> const&) (in /app/node_modules/hummus/binding/hummus.node)
==10799==    by 0xB5E71A: v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<true>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) (in /usr/local/bin/node)
==10799==    by 0xB606B1: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) (in /usr/local/bin/node)
==10799==    by 0x7748F95BE1C: ???
==10799==    by 0x7748F90D144: ???
==10799==    by 0x7748F98B87C: ???
==10799==    by 0x7748F9118D4: ???
==10799==    by 0x7748F9118D4: ???
==10799==    by 0x7748F9118D4: ???
==10799==    by 0x7748F9118D4: ???
==10799==    by 0x7748F9118D4: ???
galkahana commented 5 years ago

ok. ill look into it.

OwlyCode commented 5 years ago

I found the source of the leak and opened a PR on your library : https://github.com/galkahana/PDF-Writer/pull/140

OwlyCode commented 5 years ago

With this fix, the server that was filling 1GB of memory in 7 minutes has now been stable at 100MB for 45 minutes under the same conditions.

galkahana commented 5 years ago

thanks man!

galkahana commented 5 years ago

cool 1.0.93 has an updated PDF-Writer to fix the problem

OwlyCode commented 5 years ago

I saw your commit and I'm waiting for it to land on npm :smile: Thank you for taking time for this !