Skip to content

Memory leakage occurs when updating many characters. #1083

Open

Description

@shinsuke-ota-1201

Version used:createjs.EaselJS.version=1.00
Browser version: Chrome131.0.6778.140

Memory leakage occurs when updating many characters.

The code to reproduce it is as follows

<html>
<head>
<meta charset="utf-8"/>
<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
<script>
window.addEventListener("load", init);
var count = 0;
function init() {
var stage = new createjs.Stage("myCanvas");
var func = function() {
var text = count % 2 == 1 ? "A" : "B"
for(var i = 1; i <= 100; i++) {
for(var j = 1; j <= 100; j++) {
var t = new createjs.Text(text, "24px sans-serif", "DarkRed");
var con_name = i.toString() + '_' + j.toString();
var con = stage.getChildByName(con_name);
if(con == null) {
con = new createjs.Container();
con.name = con_name;
stage.addChild(con);
}else{
con.removeAllChildren();
}
con.addChild(t);
con.x = i * 24;
con.y = j * 24;
if(con.cacheID == null || con.cacheID == 0) {
var bounds = con.getBounds();
var margin = 4;
con.cache(
bounds.x - margin,
bounds.y - margin,
bounds.width + margin * 2,
bounds.height + margin * 2
);
} else {
con.updateCache();
}
}
}
count++;
};
setInterval(func, 500);
createjs.Ticker.framerate = 15;
createjs.Ticker.addEventListener('tick', function() {
stage.update();
});
}
</script>
</head>
<body>
<canvas id="myCanvas" width="1000" height="1000"></canvas>
</body>
</html>

This problem can be resolved by making the following modifications

createjs.Ticker.addEventListener('tick', function() { createjs.Text._workingContext.reset(); stage.update(); });

This memory leak is not Javascript memory,
commit memory rises.

This problem may be due to the fact that some CanvasRenderingContext2D objects that have been saved() are not being released by restore() or reset().

I believe this problem is a bug in the EaselJS program.
Will EaselJS fix this bug?

Or is there another solution?

Activity

  1. danzen commented on Feb 12, 2025

    @danzen
    Contributor

    Does the problem happen with just Text() or does it happen when you add a new Shape() in the same way?

  2. danzen commented on Feb 12, 2025

    @danzen
    Contributor

    Image

    I do see that a Text._workingContext is made once when createjs is called. It does not matter how many Text objects are made. It is written to with save() at the top of _drawText() and restore() is called at the bottom of _drawText(). So don't see why there would be a memory leak with only one canvas.

  3. danzen commented on Feb 12, 2025

    @danzen
    Contributor

    Do you have a local copy of createjs that you could perhaps adjust the drawText to use reset() rather than restore()

    So search for p._drawText =

    And that should be the method of Text... at the bottom is the restore() - what happens if you use reset()?

    if (!paint) {
        //  ctx.restore();
        ctx.reset();
    }

    I don't really know raw canvas enough to know the difference.

    Image

    It seems despite saying a reset will get rid of all settings, that even with a reset there, the Text holds the font, color, size, etc. for each letter as it is being drawn. But that might add processing if the styles, etc. need to keep being applied. Maybe, just reset() every 1000 times or something.

    Image

    Image

  4. danzen commented on Feb 13, 2025

    @danzen
    Contributor

    Okay - we are going to test:

    // change in @property _workingContext
    if (canvas.getContext) {Text._workingContext = canvas.getContext("2d"); canvas.width = canvas.height = 1;}
    // to
    if (canvas.getContext) {Text._workingContext = canvas.getContext("2d"); Text._workingCount=0; canvas.width = canvas.height = 1;}

    Then

    // change the p._drawText down below to:
    if (!paint) {
    	Text._workingCount++;
    	if (Text._workingCount%100!=0) ctx.restore();
    	else ctx.reset();
    }

    If you can, you do the same and let us know how it goes.

  5. danzen commented on Feb 13, 2025

    @danzen
    Contributor

    I tried to test and could not tell the difference between always restore(), always reset() and reset() after every 100.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions