Repository navigation
toArray() causes memory leaks #625
Description
Activity
The issue exists in GLTexture (src/backend/gl/texture/index.js) in the function call to
framebuffer():framebuffer() { if (!this._framebuffer) { this._framebuffer = this.context.createFramebuffer(); } this._framebuffer.width = this.size[0]; this._framebuffer.height = this.size[1]; return this._framebuffer; }In every iteration of the while loop,
this._framebufferis undefined, which causes the creation of a new framebuffer.This is called within GLTextureFloat
renderRawOutput():renderRawOutput() { const gl = this.context; const size = this.size; gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer()); gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0 ); const result = new Float32Array(size[0] * size[1] * 4); gl.readPixels(0, 0, size[0], size[1], gl.RGBA, gl.FLOAT, result); return result; }If you simply comment out the line
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer());it no longer leaks memory and appears to work fine. This looks like it's part of a larger issue with memory management and the delete() function on textures:delete() { if (this._deleted) return; this._deleted = true; if (this.texture._refs) { this.texture._refs--; if (this.texture._refs) return; } this.context.deleteTexture(this.texture); if (this.texture._refs === 0 && this._framebuffer) { this.context.deleteFramebuffer(this._framebuffer); this._framebuffer = null; } }The delete method will not properly clean up if called from user code since it will set the
this._deletedflag which will cause the method to always exit early... not sure what the solve for this is.- changed the title
[-]toArray() causes memory leaks?[/-][+]toArray() causes memory leaks[/+]on Jul 9, 2020 Looking at this now, fyi.
If we move framebuffer management to the kernel (every texture had to come from some kernel) we can store the framebuffers there and their delete would happen on when the kernel is deleted, and thus reuse framebuffers for the most part. I wrote up a small patch that adjusts this and the only memory leaks would be when using dynamic sized kernels as far as I can tell, because as far as I have seen using framebuffers with different sizes is unwise and can lead to unstable output. I'll push up my findings shortly.
Pushed changes to https://github.com/gpujs/gpu.js/tree/625-framebuffer-leak
Can you try the above branch and let me know if it resolves your issue?
This should be completely resolved in https://www.npmjs.com/package/gpu.js/v/2.10.0
What is wrong?
Using toArray() appears to cause memory leaks for immutable textures (see below).
Where does it happen?
In GPU.js, running on my Windows 7 PC, headlessgl in node.js v12.18.1.
How do we replicate the issue?
Here is the code to reproduce on my system:
Let that run and watch the node.exe memory climb forever.
If you remove the toArray() line (i.e.,
framebufferTex.toArray();) then the program no longer appears to leak memory.How important is this (1-5)?
Expected behavior (i.e. solution)
This shouldn't leak memory, I should be able to loop forever - grabbing a CPU array of my framebuffer texture each time - in a stable state.