Skip to main content
Participating Frequently
May 30, 2014
Answered

How to cleam memory in InDesign.

  • May 30, 2014
  • 2 replies
  • 2688 views

Dear all,

We are developing a extension for Adobe InDesign and after many months of development we are still stuck with various things we cannot find a proper solution to them. The extension exports a lot of images, texts, creates new pages, basically we are exporting all the content in a document as long as 300-400 pages in different assets, in JPG and PNG formats. So is really memory consuming

When running the extension we have developed, the main thread is bloqued and the InDesign is not responding and if the export we are doing is really large it just crashes InDesign. We would like to reléase memory after each page is finished, but we cannot do so. Once the complete export is finished, then memory is released, but not while the export is happening

As we export the memory is increasing more and more without releasing anything, we have tried different options, but seems like we never get to release memory as everything is blocked

How can we release memory while the extension is running ? Or is there a way to stop the extension each iteration so it releases memory?

We use the extension manager and flash builder.

Thanks!

Cesar.

This topic has been closed for replies.
Correct answer mim_Armand

You welcome,

It really depends on your code Cero, but for example if you have a for or while loop that goes for hundreds of cycles you can break it down to smaller portions, for and loop block a thread during their execution, that mean each while/for loop is a single process request no matter how big or intense it'd be, it should be done before that CPU core/thread accepts another request, but if you break that to two cycles, thread will be freed by the first request and taken back by the second one (therebetween cpu can decide about priorities and runs some short, high priority tasks before getting to work on the second loop). again, it depends on your code and your needs but for example to break a 100 time loop into 10 x 10 ones you can do:

var arrayLength = 100;

/*Before:*/

for (var i = arrayLength - 1; i >= 0; i--) {

    exportThePage(i);

};

/*After:*/

var breakPoint = 10;

var neededCycles = arrayLength / breakPoint; //obviously you need to improve these aspects since it breaks if you have 103 cycles for example!

var currentCycle = 0;

function loopBreaker(){

    if(breakPoint < arrayLength && currentCycle <= neededCycles){

        currentCycle++;

        mainLoop(currentCycle);

    } else if (breakPoint >= arrayLength) {

        alert('no need for me! just call a simple loop!')

    } else {

        alert('Im done here!');

    }

}

function mainLoop(currentCycle){

    for (var i = breakPoint - 1; i >= 0; i--) {

        exportThePage((breakPoint * (currentCycle - 1)) + i);

        alert('just finished workin on page: '+(breakPoint * (currentCycle - 1)) + i);

    }

    loopBreaker();

}

Now I didn't have a chance to test this at all (I may be able to test it tomorrow at university) (Edit: unsurprisingly there were a little error which I fixed), in adition it makes it harder to do such a thing in extendScript in absence of javascript timing events but I guess it will work if your page export process is heavy enough to prevent this code to through an stack overflow error (otherwise you need to increase breakPoint variable, or use a short sleep period or you simply don't need it really), I also hope to not have a syntax error here so please re-check it yourself.

About using GC it may (or may not) solve your memory problem but most certainly wont help any on your cpu load, it's better to re-use objects and not to destroy them every time.

PS: ah I forgot to say but there is no need really to mention that you need to change and adapt above code cause it will break easily if you have 103 pages for example instead of 100, I just wanted to show one of the approaches I'd think of,

hope it helps and gl ,

m,

2 replies

Jump_Over
Legend
May 30, 2014

Hi,

However deep of memory consuming is your code there is a "undo" stack created by ID as well on the fly.

So saving a doc or using other way to cut this stack down - could be a defender against memories error.

Jarek

mim_Armand
Inspiring
May 30, 2014

Hi,

I assume your code is in JavaScript, then here is my thoughts, (I'm pretty new in writing for in-design as well but it may help!):

  • about the blocking thread, I think it is because you used a 'for' or 'while' cycle and since JS is a single process/thread language it will pretty much block that thread till it's done, you may want to use an unblocking technique or give back the thread to OS every once in a while (like each 10 page for example) and take it back again (which may be a good time to call GC too).
  • for memory management, JavaScript has its own Garbage collector which will run when it thinks it's needed, however, if you keep live references to memory it will never get released, although in pure JavaScript there is no way to manage garbage collector (or call it when you need to), but good news is that apparently it is available in Extend-script through the function $.gc()! , bad news is that it probably wont help you (since I guess your problem is coming from somewhere else - IE not recycling memory through your cycles or simply blocking it) there is techniques to work it around as well: like Object pooling for example which is a very efficient way to manage memory in JavaScript and in programming in general which I guess will solve your memory problem entirely (instead of keeping hundreds of pages in memory you can keep just one all the time and replace it with the next page when you were done with the first one!)

hope it helps, good-luck, mim

ceroAuthor
Participating Frequently
May 31, 2014

Thanks Armand

How can we unblock the thread and back to OS every once in a while ? And how we can take it back again ? Our main issue is that we don't know how to unblock the thread as gets totally locked once we start the process and hence no way to free memory and InDesign ends up crashing all the time the document is large.

Now we are calling GC every iteration, and set null all objects to reléase.

Any ideas?

Thanks so much.

Cesar.

mim_Armand
mim_ArmandCorrect answer
Inspiring
May 31, 2014

You welcome,

It really depends on your code Cero, but for example if you have a for or while loop that goes for hundreds of cycles you can break it down to smaller portions, for and loop block a thread during their execution, that mean each while/for loop is a single process request no matter how big or intense it'd be, it should be done before that CPU core/thread accepts another request, but if you break that to two cycles, thread will be freed by the first request and taken back by the second one (therebetween cpu can decide about priorities and runs some short, high priority tasks before getting to work on the second loop). again, it depends on your code and your needs but for example to break a 100 time loop into 10 x 10 ones you can do:

var arrayLength = 100;

/*Before:*/

for (var i = arrayLength - 1; i >= 0; i--) {

    exportThePage(i);

};

/*After:*/

var breakPoint = 10;

var neededCycles = arrayLength / breakPoint; //obviously you need to improve these aspects since it breaks if you have 103 cycles for example!

var currentCycle = 0;

function loopBreaker(){

    if(breakPoint < arrayLength && currentCycle <= neededCycles){

        currentCycle++;

        mainLoop(currentCycle);

    } else if (breakPoint >= arrayLength) {

        alert('no need for me! just call a simple loop!')

    } else {

        alert('Im done here!');

    }

}

function mainLoop(currentCycle){

    for (var i = breakPoint - 1; i >= 0; i--) {

        exportThePage((breakPoint * (currentCycle - 1)) + i);

        alert('just finished workin on page: '+(breakPoint * (currentCycle - 1)) + i);

    }

    loopBreaker();

}

Now I didn't have a chance to test this at all (I may be able to test it tomorrow at university) (Edit: unsurprisingly there were a little error which I fixed), in adition it makes it harder to do such a thing in extendScript in absence of javascript timing events but I guess it will work if your page export process is heavy enough to prevent this code to through an stack overflow error (otherwise you need to increase breakPoint variable, or use a short sleep period or you simply don't need it really), I also hope to not have a syntax error here so please re-check it yourself.

About using GC it may (or may not) solve your memory problem but most certainly wont help any on your cpu load, it's better to re-use objects and not to destroy them every time.

PS: ah I forgot to say but there is no need really to mention that you need to change and adapt above code cause it will break easily if you have 103 pages for example instead of 100, I just wanted to show one of the approaches I'd think of,

hope it helps and gl ,

m,