Fabric.js: Canvas memory exceeds 4096 MB even when using canvas.clear()

Created on 24 Aug 2018  路  24Comments  路  Source: fabricjs/fabric.js

Version

2.3.5

Test Case

http://jsfiddle.net/Da7SP/2366/

Steps to reproduce

Just run the fiddle. You will see a square (formed of many tiny squares) slowly alternating between red and green. The code will continuously clear the canvas and add objects to it in a loop, but the number of canvases used for caching keeps growing until at some point the following errors are logged:

bildschirmfoto 2018-08-24 um 21 24 13

browser_bug bug

All 24 comments

Well creating 8100 rects in rapid successions, with a setTimeout of 1ms.
Is this a real use case?

canvas.clear dereference the rects, that should garbage collected with their cache canvas, unsure when this happen.

did you try to manually delete the reference to _cacheCanvas and see if that helps?

What is the real use case that made you discover the bug?

Sorry, I should have given more info about the background. In my application I have several parameters that can be changed by the user and populate the canvas dynamically. That means that these parameters can be changed many times, and each time all the objects are deleted and recreated. The fiddle is just to recreate this situation more quickly.
Deleting _cacheCanvas doesn't seem to help: http://jsfiddle.net/Da7SP/2372/

How long does it takes to get the message?
Can we accelerate it?

Ok to me does not happen in 2 minutes,
anyway i can speculate on those root causes:
Fabric creates a cache of 256x256 pixels MINIMUM for each object ( this is a setting ) it does that to ensure gpu acceleration of small things.
That means that your gpu somehow get 8000 copies of those 256x256 tiles.

256x256x4bytesx8100 = 2,123,366,400
2 gigs of stuff, if for any reason one cycle jump the cleaning you may have some problem.

How many gigabytes as your GPU?

Does it happens just in chrome? because chrome do crazy stuff to win performances.

Does disabling object caching eliminate the problem completely?

Usually it takes me no more than 10 seconds until the error is displayed. In my application I can recreate this situation by clicking several times a button that recreates all these objects, so the time interval is definitely longer than one cycle.
My MacBook Pro 2017 15'' has an integrated Intel HD Graphics 630 1536 MB and a Radeon Pro 560 4096 MB.
I'm using Safari 11.1.2 on macOS 10.13.6.
When disabling object caching the problem is gone: http://jsfiddle.net/Da7SP/2376/

i m with the previous model.
I have a m370x with 2 gigs ( but my apple on the backscreen lights up, and your don't ) but i can't replicate.

Can you try to lower the limit of the cache size as described here:
http://fabricjs.com/fabric-object-caching
to 32px and see if it helps in some way? you have probably to try harder to make it happen both on the fiddle and on the app.
Also i was trying to make a standard html page from that fiddle because is super hard to inspect performances, it looks like i m not able to inspect the code from the result iframe.

I tried running the fiddle with a cache size of 32px for several minutes and no error was logged.
I also tried the original fiddle on Chrome and Firefox, never got an error. So perhaps it is only Safari.
Is it possible to have a small Javascript sample that I could test on the different browsers? Do you have an idea which part may be causing the memory leak? Is it just allocating the canvases?

maybe could be our lazy way of deleting objects on clear?

we reset the array length to 0, instead of creating a new one

It looks like setting the array length to 0 is a valid way of releasing the objects. If you have a code snippet, I could try it out on my Mac. Can you reproduce it on Safari?

I did not try on safari in first place because there was no real indication at the top that was a safari problem ( i could have understood from the screenshot, but i wasn't so good to catch it ).

I have to park this issue for a bit, i would like to know what is happening, but this is potentially a timesink and i have no idea how safari developer team answer to question.

Replicating the fiddle in a static html page is just matter of copy pasting the fiddle code in a file called index.html and linking fabrics inside.

For me it's also not a big issue since I noticed that disabling caching altogether greatly improved performance (at least on Safari).
What I meant actually was that if you have a clue about what might be causing the leak and could provide a simple script (i.e. without a link to the fabric library, so that it is easier to debug).

oh reproducing everything in plainJs is a bit complicated, but definitely tryable

If you have many objects that you draw once or that if you draw are randomly modified, probably cache make no sense.

Cache is for long sessions in which one object is dragged around or scaled, while other are static

I also encountering this issue only in Safari, my environment is macOS 10.14.3, Safari Version 12.0.3 (14606.4.5).

+1

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

I can still reproduce it. Are there no plans to fix this?

I made the choice to add this bot for a couple of reasons:

  • alone i will never manage to handle 370+ open issues, just going over them takes the time to fix a couple
  • if there is no collaboration i will manage to fix less, so if an issue does not receive help is marked as stale and eventually closed, unless i marked it as a bug or feature or some other label.

This first round of labeling as stale will wake up people that still care for the issue and will make me focus at least on labelling unlabeled ones.

up

up, pleaseeeeee, I'm dealing with the same problem, it doesn't matter how I clear the old canvas, the memory keeps its own way to the sky T.T

If i would know where to fix it i would have done it.

As anyone find a way to verify where it happens? what objects aren't cleared?

I have a process of producing this "bug":

  1. write a big canvas (3000x7000), so it will eat the memory faster, not waste our time
  2. write a function to draw 10 SVG
  3. write a function to clear the canvas and call the function in step 2
  4. call the function in step 3 consecutively, and after that, the page will suddenly become blank
    to be more clear, open Task manager in Chrome, look at the GPU process and its memory, you will see that the memory will keep going up until it reaches the limit of hardware

share a fiddle with it

Was this page helpful?
0 / 5 - 0 ratings

Related issues

raichu picture raichu  路  4Comments

zhangzhzh picture zhangzhzh  路  4Comments

eugene-g13 picture eugene-g13  路  3Comments

bevacqua picture bevacqua  路  4Comments

mlev picture mlev  路  3Comments