skia-canvas
skia-canvas copied to clipboard
garbage collection / memory deallocation gone wrong?
tried to render my project and ran into some issues:
- first of all, seems like [email protected] leaks A LOT.
below i posted code which renders simple rectangle one time (!) and then renders to buffer as JPG 100 times. in [email protected], this process takes from 150 MiB up to 333 MiB. just a rectangle! in [email protected], though, memory usage increases from 50 MiB to 130 MiB. :thinking:
- secondly, the leakage itself is very annoying. every time i render my project (not the one listed below) i get +15 MiB from each iteration, and with [email protected] it went straight to 800 MiB RAM usage in just five minutes! unbelieveable.
anyways, here's the code:
// node --expose-gc leakage-test.js
const { Canvas } = require('skia-canvas')
async function printMem(name) {
await new Promise((r) => setTimeout(r, 1000))
global.gc()
const mem = process.memoryUsage()
const rss = (mem.rss / 1024 / 1024).toFixed(0).padStart(3)
const heap = (mem.heapUsed / 1024 / 1024).toFixed(0).padStart(3)
const external = (mem.external / 1024 / 1024).toFixed(0).padStart(3)
console.log(`${rss} MiB / ${heap} MiB / ${external} MiB / ${name}`)
}
const run = async () => {
const canvas = new Canvas(1920, 640)
const context = canvas.getContext('2d')
context.fillStyle = 'red'
context.fillRect(300, 500, 250, 170)
for (let i = 0; i < 100; i++) {
await canvas.toBuffer('jpg')
await printMem(`iteration #${i}`)
}
}
run().catch(console.error)
i tried many methods: using one shared canvas, clearing that canvas after every iteration via context.clearRect(0, 0, canvas.width, canvas.height), forcing global.gc() every iteration — nothing worked
I have the same issue with buffers. My application quickly runs out of memory.
I tried your code using node-canvas, and no leaks. I will be switching to that.
I have the same issue with buffers. My application quickly runs out of memory.
I tried your code using node-canvas, and no leaks. I will be switching to that.
the problem is that node-canvas actually sucks, it can't do a lot of things skia-canvas can. for example, simple and basic gaussian blur of the photo is nearly impossible (if not impossible at all) to do with node-canvas, but with skia-canvas it's as easy as two or three lines of code =D
the problem is that node-canvas actually sucks, it can't do a lot of things skia-canvas can. for example, simple and basic gaussian blur of the photo is nearly impossible (if not impossible at all) to do with node-canvas, but with skia-canvas it's as easy as two or three lines of code =D
I know what you mean ha. The blur was the main reason i opted for skia-canvas over node-canvas in the first place.
But since your issue was given no attention what so ever, there was no guessing when or even if this issue will ever be resolved. I had to either accept that there would be no blur, or accept that the app would experience a fatal crash 20 times per day. I can't speak for you, but for my use-case that choice was easy.
It's unfortunate for anyone where the blur is a more necessary feature though, because afaik there really are no alternatives.
I have the same issue. But I tried to set canvas.gpu = false, and no leaks.
I have the same issue. But I tried to set
canvas.gpu = false, and no leaks.
Can confirm that this worked for me, solved the memory leak issues. I imagine this limits some performance in certain situation but for my case I wasn't taking advantage of the GPU acceleration of the library anyway so totally fine.