Skip to content

Free the usage graph after emitting errors#392

Open
ondrejmirtes wants to merge 1 commit into
shipmonk-rnd:masterfrom
ondrejmirtes:free-usage-graph-after-emitting-errors
Open

Free the usage graph after emitting errors#392
ondrejmirtes wants to merge 1 commit into
shipmonk-rnd:masterfrom
ondrejmirtes:free-usage-graph-after-emitting-errors

Conversation

@ondrejmirtes

Copy link
Copy Markdown

Problem

DeadCodeRule::processNode(CollectedDataNode) runs once per process, at result finalization in PHPStan's main process. After processKnownCollectedUsages() has turned the accumulated state into errors, $traitMembers, $memberAlternativesCache, $blackMembers and $usageGraph are dead weight retained until the process exits.

Found while instrumenting PHPStan memory retention on the ShipMonk backend: a per-service retention census attributed ~90k objects to the rule instance on a 2.4k-file slice (UsageOrigin, ClassMethodRef/ClassPropertyRef/usages, BlackMember), and an interleaved A/B benchmark on the full 25k-file codebase measured −55 MB main-process peak RSS (3.07 GB → 3.02 GB, consistent across duplicate runs) with byte-identical error output and no time cost.

Change

Reset the four members at the end of processNode().

Deliberately kept: $typeDefinitions and $mixedClassNameUsages — the DiagnoseExtension::print() reads them after analysis (clearing them broke testDiagnoseMixedCalls & co., which is how they earned their exemption). DebugUsagePrinter received its own copies of the analysed members earlier (PHP array value semantics), so -vvv debug output is unaffected.

composer check:tests (702 tests), check:types, check:cs pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NrTvR9j1mW2NNNC8RkuTsF

processNode(CollectedDataNode) runs once per process. After
processKnownCollectedUsages() has turned the accumulated state into errors,
$traitMembers, $memberAlternativesCache, $blackMembers and $usageGraph are
dead weight — measured at ~90k retained objects on a 2.4k-file codebase and
about 55 MB of main-process peak RSS on a 25k-file one, held until the
process exits.

$typeDefinitions and $mixedClassNameUsages are kept: the DiagnoseExtension
print() reads them after analysis. DebugUsagePrinter received its own copies
of the analysed members earlier (PHP array value semantics), so debug output
is unaffected — covered by the existing testDiagnose* tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NrTvR9j1mW2NNNC8RkuTsF
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.

1 participant