• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers

Memory leak iterating collections

Community Beginner ,
Dec 11, 2022 Dec 11, 2022

Copy link to clipboard

Copied

Hello,

 

I have a UXP script that iterates over all TextStyleRanges of all Paragraphs of all PageItems of all Pages of a document, and it seems to be leaking memory.

My document has 140 pages, each page has 1-3 page items, each having 15-20 paragraphs with a few TextStyle ranges each. At about 20 pages, memory consumption is already 4GB and it quickly grows to 100%, at which point the entire process slows down so much that it takes hours to process the entire document.

I feel like the collections provide only a facade to InDesign object, which are only created as needed, except once they are created they remain in memory.

Is there any way to release a collection to reclaim the memory? Or any other workarounds?

 

For reference, here is how I am iterating over my document:

const pages = app.activeDocument.pages.everyItem().getElements();
  for(let iPage = 0; iPage < 20; iPage++){
    const page = pages[iPage];
    const pageItems = page.allPageItems;
    for(let iPageItem = 0; iPageItem < pageItems.length; iPageItem++){
      const pageItem = pageItems[iPageItem];
      if (!pageItem.paragraphs) {
        continue;
      }
      const paragraphs = pageItem.paragraphs.everyItem().getElements();
      for (let iParagraph = 0; iParagraph < paragraphs.length; iParagraph++){
        const paragraph = paragraphs[iParagraph];
        const ranges = paragraph.textStyleRanges.everyItem().getElements();
        for (let iRange = 0; iRange < ranges.length-1; iRange ++){
          const range = ranges[iRange];
        }
      }
    }
  }

Any help is much appreciated 🙂

David

TOPICS
UXP Scripting

Views

368

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 12, 2022 Dec 12, 2022

Copy link to clipboard

Copied

UXP brought modern ES6 syntax so why not use it 😉 I don't know if that would solve your memory leak issue but it could discard the chain of loops you are using. Give it a try and see:

function main(){
  let pages = app.activeDocument.pages.everyItem().getElements();
  pages.forEach( page => {
    let pageItems = page.allPageItems;
    pageItems.forEach( pageItem => {
      if(pageItem.hasOwnProperty("paragraphs")){
        let paragraphs = pageItem.paragraphs.everyItem().getElements();
        paragraphs.forEach( paragraph=> {
          let ranges =  paragraph.textStyleRanges.everyItem().getElements();
          ranges.forEach( range => {
            console.log(range);
          })
        })
      }
    });
  })
}

main();

HTH

Loic

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 12, 2022 Dec 12, 2022

Copy link to clipboard

Copied

Or even shorter:

const ranges = app.activeDocument.stories.everyItem().textStyleRanges.everyItem().getElements();

The memory leak you see may be caused by the repetitive const declarations inside the loops.  See what happens when you declare them as variables outside the loops, at the beginning of the script.

 

And finally, UXP scripting is still work in progress, it'll get better over time. At the moment ExtendScripts are considerably quicker than equivalent UXP scripts when they make heavy use of InDesign's DOM. Pure JavaScript is quicker in UXP, but since every InDesign script touches the DOM for the time being you'll be better off with ExtendScript.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 12, 2022 Dec 12, 2022

Copy link to clipboard

Copied

Oh gosh, yes obviously 😛

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Dec 12, 2022 Dec 12, 2022

Copy link to clipboard

Copied

Hi Peter,

Thanks for your reply. I unfortunately can't use your one liner since I need to keep track of the relationship between testStyleRanges and their paragraphs and their pages. The code I posted was to illustrate the issue, but I do actually need some info from the page and paragraph in my script.

Repeated declarations really shouldn't be a problem since they would get garbage collected as soon as they fall out of scope.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 12, 2022 Dec 12, 2022

Copy link to clipboard

Copied

Ok. But do try without repeated declarations. "Shouldn't be a problem" doesn't really cut it with InDesign scripting. And remember that you're better off with ExtendScript for the time being.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Dec 12, 2022 Dec 12, 2022

Copy link to clipboard

Copied

LATEST

Hi,

 

Re. "I need to keep track of the relationship between testStyleRanges and their paragraphs and their pages.". Starting from Peter's one-liner, you can access the paragraphs collection. And keep climbing up to the page. Not sure what would be the quickest though.

Loic

Loic

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines