psalm: Memory Leak in AtomicMethodCallAnalyzer.php on line 203
I’ve been running Psalm for a while without issue, but suddenly on upgrading to 3.12 I started seeing this out of memory error.
I am currently running the newest version: Psalm 3.14.1@9822043ca46d6682b76097bfa97d7c450eef9e90
and still seeing the issue.
I’ve increased the allowed ram upto 32 gb and I still get the error, which leads me to believe there is a memory leak.
Scanning files...
Analyzing files...
PHP Fatal error: Allowed memory size of 8589934592 bytes exhausted (tried to allocate 4294967304 bytes) in /Users/jdonat/.composer/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php on line 203
Fatal error: Allowed memory size of 8589934592 bytes exhausted (tried to allocate 4294967304 bytes) in /Users/jdonat/.composer/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php on line 203
Using the --debug
flag I was able to narrow it down to this file - I’ve whittled several thousand lines of code down to just the part that seems to be triggering the error.
Getting rid of any of these lines seems to make the error go away.
Getting rid of any of the IFs makes the error go away.
<?php
namespace Mappers\User;
use Objects\User\UserAwarenessInterfaces\AdminAwareUserInterface;
use Objects\User\UserAwarenessInterfaces\ContactInformationAwareUserInterface;
use Objects\User\UserAwarenessInterfaces\CourseAwareUserInterface;
use Objects\User\UserAwarenessInterfaces\RidAwareUserInterface;
use Objects\User\UserAwarenessInterfaces\RosterAwareUserInterface;
use Objects\User\UserFactory;
class UserMapper {
protected $factory;
public function __construct(
UserFactory $userFactory
) {
$this->factory = $userFactory;
}
protected function makeFromRecords( array $data ) {
$user = $this->factory->make(0, 0, 0, 0, 0, '', '', '', '', '', '', 0, 0, 0, 0, false, 0);
if( $user instanceof CourseAwareUserInterface ) {
//foo
}
if( $user instanceof AdminAwareUserInterface ) {
//foo
}
if( $user instanceof RosterAwareUserInterface ) {
//foo
}
if( $user instanceof RidAwareUserInterface ) {
//foo
}
if( $user instanceof ContactInformationAwareUserInterface ) {
$user->setEmailAddress('');
}
}
}
I suspected maybe the interfaces formed a triangle or something, but as far as I can tell none of them reference any of the other ones.
I’m not sure how much this helps, but here’s a very chart of the inheritance tree however.
I’d personally love to just dump the full code up here for you guys, but I can’t. If you think it will help, I can probably go through and anonymize them as best of my ability, but I’m avoiding the effort currently…
Let me know if there’s anything else I can provide to help you with this. I’m very happy to help.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 16
Commits related to this issue
- Fix #4010 – don’t create interface intersections unless there’s no overlap — committed to danog/psalm by muglug 3 years ago
Thanks @dbrekelmans for the reproducer!
Ok, this should be fairly simple to work around
Psalm build a lot of complex types internally: https://psalm.dev/r/a1e99c7462