jsreport / jsreport-core

The minimalist jsreport rendering core
GNU Lesser General Public License v3.0
85 stars 24 forks source link

Memory leak in tests #49

Closed LubomirIgonda1 closed 4 years ago

LubomirIgonda1 commented 4 years ago

Hi I try to write some tests but I figured out that after couple of tests the memory usage is dramatically increase (see pic.)

image

ENV: WIN 10 (1909) node 10.15.0

Here is test repo just run npm run test command https://github.com/Bubomir/jsreport-memory-leak

It looks like this issue https://github.com/jsreport/jsreport/issues/78 but i am not absolutely sure Thanks for any help

bjrmatos commented 4 years ago

thanks for the issue, i did not know that jest has such a feature to check the memory after each test, it looks very handy.

i've investigated a bit and i found the problem, the memory leak happens because of this line. what this line does is to start a routine that cleans temp files used by the rendering at specific intervals, seems like such interval holds memory and prevents the garbage collector to claim that memory, this means that for every instance of jsreport you will have an interval that is holding memory during the lifetime of the process. since you are creating a new instance of jsreport per each test then you can easily see how the memory grows per each instance because of such intervals.

this is the result for me when trying your case:

Captura de pantalla 2019-11-22 a la(s) 5 50 53 p  m

and this is the result after updating some code to prevent such intervals to hold memory.

Captura de pantalla 2019-11-22 a la(s) 6 04 09 p  m

we are going to discuss this internally and decide what is the proper fix based on my investigation.

the workaround for you is to disable this cleanup, for example you can put to your config this autoTempCleanup: false and it will prevent the intervals to be created:

const jsreportInstance = jsreport({
    autoTempCleanup: false,
    templatingEngines: {
        strategy: 'in-process'
    },
    extensions: {
        'chrome-pdf': {
            launchOptions: {
                args: ['--no-sandbox']
            }
        }
    }
}).use(jsreportChrome()).use(jsreportEjs()).init()
bjrmatos commented 4 years ago

this is now fixed (will be part of next release).

you need to call reporter.close (returns promise) after each jsreport instance becomes longer needed (probably somewhere in afterEach or afterAll test hooks, it depends on how you structure your tests), this call ensures that all the internals are properly cleaned (including the interval of the reaper).