Open NullSoldier opened 3 years ago
In my case the context doesn't take as much memory, only 3MB... but sadly a bigger problem is the "loadImage" function never releases memory either.
I modified your test and looped through it 10 times, with additional loadImage call and a timeout... seems like it never releases the memory.
rss / heap / ext / name
31 MiB / 3 MiB / 0 MiB / start
31 MiB / 3 MiB / 0 MiB / canvas created
34 MiB / 3 MiB / 0 MiB / context created
111 MiB / 3 MiB / 0 MiB / nulled context
112 MiB / 3 MiB / 0 MiB / nulled canvas all
111 MiB / 3 MiB / 0 MiB / nulled img
112 MiB / 3 MiB / 0 MiB / waited 10 seconds
rss / heap / ext / name
112 MiB / 3 MiB / 0 MiB / start
112 MiB / 3 MiB / 0 MiB / canvas created
112 MiB / 3 MiB / 0 MiB / context created
112 MiB / 3 MiB / 0 MiB / nulled context
112 MiB / 3 MiB / 0 MiB / nulled canvas all
112 MiB / 3 MiB / 0 MiB / nulled img
112 MiB / 3 MiB / 0 MiB / waited 10 seconds
... [9 iterations later]
rss / heap / ext / name
112 MiB / 3 MiB / 0 MiB / start
112 MiB / 3 MiB / 0 MiB / canvas created
112 MiB / 3 MiB / 0 MiB / context created
112 MiB / 3 MiB / 0 MiB / nulled context
112 MiB / 3 MiB / 0 MiB / nulled canvas all
112 MiB / 3 MiB / 0 MiB / nulled img
112 MiB / 3 MiB / 0 MiB / waited 10 seconds
Thanks for the nice repro steps. I can't reproduce this on Windows or Linux however:
$ node --expose-gc ./1738.js
rss / heap / ext / name
36 MiB / 3 MiB / 0 MiB / start
37 MiB / 3 MiB / 0 MiB / canvas created
37 MiB / 3 MiB / 0 MiB / context created
37 MiB / 3 MiB / 0 MiB / nulled context
37 MiB / 3 MiB / 0 MiB / nulled canvas all
I'm surprised to see 400 MB allocated when the context is created.
If this is truly unique to MacOS, then it's possible it has to do with the system memory allocator.
Any other tips for reproducing it?
I'm almost positive this has to do with pango preloading system fonts. On macOS, for example, when you create the first canvas, pango locates every font installed on the system and preloads all of them into memory.
I wonder if there is a way to tell pango to look elsewhere for fonts (e.g. in an empty directory), and not preload all the system fonts.
IIRC there is one Pango FontMap per process, and it would be lazily created, so that could definitely explain the statistics in the OP. You should see that to varying degrees on every platform though. Here is the Windows code loading all system fonts when a PangoWin32FontMap is created.
macOS ships with fonts for many of the world's languages, and some fonts, like CJK or emoji, can be pretty huge. It could be that macOS simply has more fonts, or that it's parsing glyph paths unnecessarily.
I wonder if there is a way to tell pango to look elsewhere for fonts (e.g. in an empty directory), and not preload all the system fonts.
I think we should do our own font selection like browsers do, and ship Canvas with a small basic set of fonts.
I think we should do our own font selection like browsers do, and ship Canvas with a small basic set of fonts.
I wholeheartedly agree! 👍🏻
Issue or Feature
When I allocate a context, there is seemingly nothing I can do to free the memory used. It seems to keep the memory without being freed. Also... If I clear the canvas and allocate a second one, it seems to re-use the buffer of the first canvas under certain conditions.
Other oddities are that reallocating multiple canvas and context does not use more memory seems to re-use memory pool if you allocate the canvas next to each other...
but doubles memory when allocated interleaved
Steps to Reproduce
Your Environment