Skip to content

Reduce memory consumption of large literal arrays in 2.3.x - #6727

Open
alfredbez wants to merge 6 commits into
phpstan:2.3.xfrom
alfredbez:fix/literal-array-memory-2.3
Open

alfredbez wants to merge 6 commits into
phpstan:2.3.xfrom
alfredbez:fix/literal-array-memory-2.3

Conversation

@alfredbez

@alfredbez alfredbez commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Fixes phpstan/phpstan#15452

Reproducer: https://github.com/alfredbez/phpstan-literal-array-memory-reproducer

Avoid retaining expression results and closures for every scalar item in large literal arrays. Keep results needed by by-reference items, and mirror the changes in the Turbo extension.

On a synthetic 30,000-item array, peak worker memory dropped from 229 MB on the base commit to 126 MB with this change. Analysis results were unchanged.

Verified locally: full test suite with and without Turbo, differential checks, strict native build and UBSan. Added callable-array dependency coverage, including a PHP 7.4 analysis target that detects the escaped mutation. The new GitHub CI run is pending.

@ondrejmirtes

Copy link
Copy Markdown
Member

Hey, please submit an issue with the description and reproducer first, thank you.

alfredbez and others added 5 commits October 11, 2026 15:55
ScalarHandler builds the constant types of the literal scalars eagerly
and hands them over precomputed, without a typeCallback closure, like
its PHP twin. ArrayHandler stores only each non-scalar item's
[type, nativeType] pair, collects the items' dependencies while walking
them, and evicts the items' expression results once their callback ran,
unless a by-reference item keeps the literal alive;
ExpressionResultStorage gains the native removeExpressionResult(). The
item-type resolution of the type callback, the absorbed-items walk and
the callable-array dependencies re-derive the scalar and TypeExpr types
from their nodes, as the twin does. On the PHP side, fix the import
order and use the early exit the coding standard asks for.
A [Foo::class, 'method'] array makes its file depend on what calling it
returns, so a change of the method's return type re-analyses it; arrays
whose first item is not definitely a class-string (a maybe-class-string,
an object) add no such dependency.
Configure the target PHP version, not the test runtime, to expose
class-string|object callable dependencies and detect the escaped mutant.

Amp-Thread-ID: https://ampcode.com/threads/T-01a129b7-7bd7-771c-89da-39bb43f0eed7
Co-authored-by: Amp <amp@ampcode.com>
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.

High memory use when analysing large literal arrays

2 participants