[BUG] Imaging API memory leak when reading pixel data

,

Hi team,

I’m developing a UXP plugin for live updating Blender textures from Photoshop. For this I need to frequently read the image pixel data. Everything was working exceptionally well until I noticed that the plugin is leaking huge amounts of memory. I spent half a day debugging this and tried everything I could think of. Now I’m 99% sure that this little code snippet is leaking all of the pixel data:

async function memoryLeakTest() {
    let pixels = await modalWrapper(async () => await imaging.getPixels({}), "Reading image pixel data");
    const { imageData, sourceBounds, level } = pixels;
    const pixelData = await imageData.getData();
    imageData.dispose();
}

The function reads all pixel data from the active document and does nothing with it. When commenting out the call to imageData.getData() no memory leak happens.

I created a simple test plugin which would just call this function when a button is pressed. After hitting the button the Photoshop process memory increases roughly by the size of the pixelData buffer. This happens every time I press the button until the OS runs out of memory. You can see it very clearly when you use a large 5k image for testing.

I tested this on Windows and MacOS using Photoshop version 26.5.

You can also use the Imaging API example plugin (imaging-test) to reproduce the memory leaks.

Can you please check this on your end? I’m running out of options. In this state the plugin cannot be given to users.

Cheers.

1 Like

try: pixels.imageData.dispose();

This sounds more like the use case for Generator Plugins/Image Assets.

The Imaging API is not intended as an export mechanism.

Thanks for your responses.

I simplified my example above to make it more obvious that dispose() is correctly called. As I said these three lines are leaking what appears to be all of the memory allocated for the pixels. Even though dispose() is called. This can easily be reproduced on Mac and Windows.

@samgannaway Please don’t worry about what I’m doing with the pixel data later. I should not have mentioned the Blender thing. The memory leak happens for everybody who calls imageData.getData() no matter the use case.

async function memoryLeakTest() {
    const pixels = await modalWrapper(async () => await imaging.getPixels({}), "Reading image pixel data");
    const pixelData = await pixels.imageData.getData();
    pixels.imageData.dispose();
}

I tried to reproduce the issue on the 2024 version of Photoshop and everything work fine there. So it appears to be a regression.
The memory leak is reproducible in PS 2025 version 26.5.0 but not reproducible in PS 2024 25.12.2 (PS 2024).

Memory leaks are just one of Photoshop’s features. They are all over the place. It is one of the worst maintained applications around, maybe second only to those maintained by Autodesk.

I don’t mind a small memory leak here and there. But leaking a potentially huge buffer of uncompressed image data is a big deal. Images these days are very high resolution and a plugin which processes pixel data can easily leak 100 MB of memory in a single invocation.

I asked Copilot the following question and chose the option “Deep Research -10 min Detailed Report with References”

PROMPT: - I have written a photoshop plugin in UXP. Each time I run the plugin, the available memory reduces (until I close and reopen Photoshop). I have read on some forums that Photoshop is prone to memory leaks under these conditions. Can you please review and summarise people’s findings on this matter. If any mitigations have found, can you please also summarise these in simple terms.

The resultant report cannot be uploaded here.

Key findings are as follows.

Key Findings

  • Memory leaks in Photoshop when running UXP-based plugins repeatedly are a well-documented issue, particularly when using the Imaging API’s getPixels() and getData() methods.

  • The leak is a regression in Photoshop 2025, not present in 2024, and affects both Windows and macOS platforms.

  • Explicitly calling dispose() is necessary but not always sufficient to prevent leaks in the latest versions.

  • General memory growth in Photoshop (even without open documents) is common, with memory only released upon application restart.

  • Plugin reloads during development can accumulate memory leaks, necessitating periodic restarts or full unloads.

  • Mitigation strategies include limiting image/region size, chunked reads, alternative APIs, cleaning up plugin storage, capping memory allocation, updating or reverting Photoshop versions, and resetting preferences.

  • Adobe acknowledges high memory usage as partly by design, but excessive or unbounded growth is considered a bug and should be reported.

  • Developer tools such as the UXP Developer Tool and Chrome DevTools are essential for monitoring and debugging memory usage.

Some of this may be a bit circular in that it quotes the memoryLeakTest() function given above.

If you wish to read the full report you need to type the preceding prompt into Copilot and treat the outcome with the same sceptism as you would any AI tool.

Unless it gives any specific example of code where it leaks, it is not very useful. It is niche. It doesn’t find many other pages with this API. AI does not have much to learn from or search in. It might just vaguely reiterate stuff that is already in this forum.

Imaging API is done in C++ where garbage collector does not exist, but is binded into JS where GC works on its own. V8 should take care of that if the values are no longer referenced in any way. It is likely leak would be in C++ where we do not have any insight into what is going on under the hood.

I never tried this property and I am not sure if this is good indicator but maybe do you have in v8HeapSize any huge number?

2 Likes

Thank you for that. It took me a while to get up to speed on this.

The Claude AI tool told me this.

v8HeapSize: 4098: - This is the V8 JavaScript engine heap size in kilobytes (~4MB). This represents the memory your plugin’s JavaScript code is currently using. This is quite lean for a plugin. Only be concerned if you see this growing continuously over time (memory leak indicator).

I only get ‘4098’ even after repeated runs. In any case, this is small compared to the size of the apparent leak (up to 1GB per iteration).

My plugin has an option for high- and low-resolution processing. The image sizes addressed by get.Data() are different for these options. The apparent leakage that I get seems to be independent of image size. The opening post seems to imply otherwise?

At the conclusion of processing, I have from getPluginInfo …… “pendingDeferralCount”: 2. I need to investigate this.

Some AI tools seem to suggest that you need to use

const pixelData = await new pixels.imageData.getData();

It suggests that you need to create a new copy of the data so that Photoshop is free to delete the original.