text2d not being cleaned by javascript garbage collector

pcm@pcmxa.com's icon

Hi,

I have a script that creates new jit.gl.text2d objects and adds them to an array. When the array reaches a certain length, I want to remove the oldest item in the array. While I can remove the item from the array, the jit.gl.text2d object is not being deleted. I have tried slice, shift, setting a variable = to the object and then deleting the variable and setting it null. I have done this aftef setting the text of the jit.gl.text to null. No matter what it doesn't get deleted and eventually the script crashes Max. Any suggestions or pointers on removing objects in javascript (I have searched the web but everything seems to indicate that slicing the array should do it)? Thanks

code:
' autowatch = 1;
inlets = 1;
outlets = 1;
var i = -1;
var textColor = 0.5;
var textLineArray = new Array();
var deadText=null;

function textLineMaker(a){
post("textLineArray length is " + textLineArray.length +"n");
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////tests array length and removes oldest item.
if(textLineArray.length>10){
post("delete calledn");
deadText = textLineArray.shift();
deadText = null;
post("deadText is " + deadText + "n");
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////Sets texts variables
var xMultiplier = Math.sin(Math.random()*360);
if (xMultiplier < 0){
xMultiplier = -0.5;
} else {
xMultiplier = 0.5;
}
var yMultiplier = Math.sin(Math.random()*360);
if (yMultiplier < 0){
yMultiplier = -1;
} else {
yMultiplier = 1;
}
var xPosition = Math.random()*xMultiplier;
var yPosition = Math.random()*yMultiplier;
var zPosition = 0.0;
textColor = (Math.floor(Math.random()*125+50))/256;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// creates the jitterObject
textLineArray.push(new JitterObject("jit.gl.text2d", "werds"));
textLineArray[textLineArray.length-1].antialias = 1;
textLineArray[textLineArray.length-1].align = 1;
textLineArray[textLineArray.length-1].color = [textColor,textColor,textColor,1.];
textLineArray[textLineArray.length-1].position = [xPosition,yPosition,zPosition];
//textLineArray[iterator].rotate = 90;
textLineArray[textLineArray.length-1].font("Arial");
var textSize = Math.floor(Math.random()*10)+4;
textLineArray[textLineArray.length-1].size(textSize);
textLineArray[textLineArray.length-1].face("bold");
textLineArray[textLineArray.length-1].tracking = 1;
textLineArray[textLineArray.length-1].screenmode = 1;
textLineArray[textLineArray.length-1].depth_enable = 0;
textLineArray[textLineArray.length-1].text(a);
textLineArray[textLineArray.length-1].draw();
}

'

Andrew Pask's icon

You cannot know in JS when it will do garbage collection. If you need to call it,

try calling

gc();

in your script at the appropriate point.

Cheers

-A

pcm@pcmxa.com's icon

thanks for the suggestion but it doesn't seem to work. I would think that shifting the array to a variable and then resetting the variable would remove all references to the object freeing it up for removal, but it just doesn't happen. Something must be referencing the text2d object still, but for the life of me I don't know what.

pcm@pcmxa.com's icon

HTH,

Thanks so much for the help. Your script is far more elegant than mine. Unfortunately, it still crashes Max. I have modified the patch you built to allow dumping a massive amount of text into the script. I also changed the script to just cut the oldest text once it reaches the correct length. On my machine it runs for about 15-20 minutes before crashing max. I am attaching a zip with the changes. Thanks for your help.

pcmxa

753.MemLeak.zip
zip
Andrew Pask's icon

ok, we think there might be some kind of leak here. The text2d object is getting GCd ok, but there is some other leak.

In the meantime, we'd suggest a workaround to use one jit.gl.text2d object @automatic 0, which walks an array, changes the positions, colors and text and renders the text explicitly like the following:

// to add to the text array:

var newline = new Object();
newline.str = thestring;
newline.color = [Math.random ( ), Math.random ( ), Math.random ( ), Math.random ( )];
newline.position = [Math.random ( ) - 0.5, Math.random ( ) - 0.5, 0.] ;
text.push(newline);

// to draw:

for (i=0; i
text2dobj.text(text[i].str);
text2dobj.color = text[i].color;
text2dobj.position = text[i].position;
text2dobj.draw();
}

Thanks for the report

-A

pcm@pcmxa.com's icon

Thanks, that works great for that part of the patcher. the trouble is I need to also have two other groups of text2d objects animating. One takes a line of text it is fed and moves it from the middle of the screen to the bottom. The other takes a number of lines all at once and moves them up to the top. To do this I built arrays to hold the text2d objects and then scripted their movement. This got around making new or deleting old text2d objects. There are always the same amount (the original ones) that are animated. I thought this would get around the memory leak but it hasn't seemed to. I am still getting max crashes stating max crashed due to java low memory. I am also zipping the relevant files below (not patcher yet I need to simplify this huge one I am working with) but here is the script that takes single lines and moves them to the bottom and then unloads each one by one after a certain number are loaded. If anyone can point out where the leak is or how to adopt Andrew's suggestion, I would be exstatic.

autowatch = 1;
            inlets = 1;
            outlets = 2;

           ////set the maximum number of lines and initial conditions

            var textLine = "Hello";
            var i = -1;
            var line = 0;
            var numberOfLines = 18;
            var maxLines = 19;
            var moveAmount = 0.005;
            var minHeight = -0.75

            ////build array of text2d objects

            var textLineArray = new Array();
            for (j=0;jnumberOfLines){
                    //    return;
                   // }

                    ////set the argument received from a text file to a global variable
                    ////and set the proerties and text of the corresponding text2d object in the array
                    textLine = a;
                    textLineArray[i].color = [1.,1.,1.,1.];
                    textLineArray[i].position = [0.,0.,0.];
                    textLineArray[i].font("Arial");
                    textLineArray[i].size(14);
                    if (i==0){
                        textLineArray[i].size(20);
                    }

                    ////draw the text and call the loading function
                    textLineArray[i].text(textLine);
                    textLineArray[i].draw();
                    lineMover();
            }

            ////functions that load the timers to move the text
            function lineMover(){
                    loadIntervalIDArch.repeat();
            }

            function lineUnloader(){
                    unloadIntervalIDArch.repeat();
            }

///////function that moves the text and fades in the color

function loadText(){

    /////cancel the unload timer if it is still going

    unloadIntervalIDArch.cancel();
     //post("loadTextArchive called");

    /////check to see if the text is above it bottom position, if so
    /////move the text and lighten an incement
     if (textLineArray[line].position[1] >= minHeight){
        //post("move called");
        var i = textLineArray[line].position[1];
        var c = textLineArray[line].color[0];
        i -= moveAmount;
        c= textLineArray[line].position[1]/minHeight;

        /////set the maximum color level

        if (c>=0.7){
            c=0.7;
        }
        //post(c);

        ////set the position and color

        textLineArray[line].position = [0.0,i, 0.0];
        textLineArray[line].color= [c,c,c,1.];
        //post("movedn");
    }

    ////if text has reached minum height set new minimum height and increment the line number
    ////also cancel the movement timer

    if (textLineArray[line].position[1] = numberOfLines){
        loadIntervalIDArch.cancel();
        minHeight = -0.75;
        line = 0;
        //post(line);
        lineUnloader();;
        outlet(0,"bang");
    }
}
    ////unloads the text.  is exctly opposite from loading text

function unloadText(){
     loadIntervalIDArch.cancel();
    //post(line + "n")
     //post("unloadTextArchive calledn");

 //// if the text2d object is not off the screen move it down and fade it out

     if (textLineArray[line].position[1] >= -1.){
        //post("move called");
        var i = textLineArray[line].position[1];
        var c = textLineArray[line].color[0];
        i -= moveAmount;
        c-=(1-(line*0.025))/40;
        if (c= numberOfLines){
        unloadIntervalIDArch.cancel();
        post("unload cancled");
       minHeight = -0.75;
        line = 0;
        //post(line);
        removeText();
        outlet(1,"bang");
    }
}
786.js_files.zip
zip