Skip to content

Conversation

@Toflar
Copy link
Contributor

@Toflar Toflar commented Aug 28, 2025

Not something you would notice when running a regular composer update or so because there are other - much more important - factors that influence memory usage. However, if you use e.g. the ComposerRepository pretty much isolated like I do in https://github.com/terminal42/composer-lock-validator, the fact that we're keeping all provider data in memory for all the packages provided is quite noticeable - the more packages, the more memory.
This is because the promises cause $contents to never be cleaned up by GC as it is used until the promise is finally resolved.

Loading packages in batches instead of all at once prevents such potential memory allocations quite nicely:

Bildschirmfoto 2025-09-18 um 11 50 43 Bildschirmfoto 2025-09-18 um 11 47 24

So json_decode() still allocates 83 MB in my case in total but because it does it in junks now, we reduce peak memory usage.

@Toflar Toflar force-pushed the fix/memory-improvement branch from db0933e to 4267c63 Compare August 28, 2025 20:47
@Seldaek Seldaek added this to the 2.8 milestone Sep 17, 2025
Copy link
Member

@Seldaek Seldaek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I see this is trading off memory use at the cost of reading the file twice, and json decoding it twice.. I'm not super happy by the trade-off tbh. Will investigate this further as I wanted to try something anyway on the cache front..

@Toflar
Copy link
Contributor Author

Toflar commented Sep 17, 2025

Right. It's already sort of not very efficient now, though. It reads the entire cache file just for the last-modified property. Could be done a lot more efficiently by storing meta data either in a file alongside the actual cache file - or using some JSON streaming stuff which as I wrote, might be hard to find re-usable libraries with our current minimum supported PHP version 😊

@Seldaek
Copy link
Member

Seldaek commented Sep 17, 2025

So I tried storing cache files as <?php return [...] and include them instead of file_get_contents+json_decode.. But for some reason this is much slower.. It does save a bit of memory but this is not worth it really.

I don't fully grasp why this is.. But anyway this isn't helping so I'll investigate your patch closer.

@Seldaek
Copy link
Member

Seldaek commented Sep 17, 2025

Interestingly I don't see a memory improvement, just an almost 2x slowdown with your patch.

I tried just reading the last-modified flag by doing a fopen+fseek to the end, and reading the last 80 chars to extract it, but that doesn't improve anything either.. Not sure what is going on today :D

@Toflar Toflar changed the title Reduce memory usage in ComposerRepository Reduce memory usage in PoolBuilder Sep 17, 2025
@Toflar
Copy link
Contributor Author

Toflar commented Sep 17, 2025

Different approach: Simply chunk the loading of packages in the PoolBuilder. This also has the advantage that it covers all sorts of memory/cache build up cases within all kinds of repositories, not just the ComposerRepository specifically.
All it does is instead of loading e.g. 250 packages at once, we now chunk into batches of 50 packages giving the GC the opportunity to jump in and free memory.
This fixes my issue (from 100 MB down to 47 MB) and I couldn't see any negative effects on a general composer update - performance is not affected as far as I could tell.

Diff best viewed with hiding whitespace - it's basically just one more loop.

@Toflar Toflar force-pushed the fix/memory-improvement branch from e1543c9 to 86d92a5 Compare September 17, 2025 19:22
@Seldaek Seldaek force-pushed the fix/memory-improvement branch from 19623b8 to 6ae0656 Compare September 18, 2025 09:38
@Seldaek Seldaek changed the base branch from main to 2.8 September 18, 2025 09:38
@Seldaek Seldaek merged commit c423a03 into composer:2.8 Sep 18, 2025
19 of 21 checks passed
@Seldaek
Copy link
Member

Seldaek commented Sep 18, 2025

Thanks

@Toflar Toflar deleted the fix/memory-improvement branch September 18, 2025 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants