Skip to content

Unreliable on PHP 8.2 and newer #182

Open

Description

@Ocramius

The design behind this component makes it very hard to port it to later PHP 8.2 versions and newer: likely scrapping it, or going back to the drawing board with it.

Measuring memory before/after from a high-level perspective is insufficient: we may need to rely on an extension that counts allocations/deallocations instead.

Activity

  1. added this to the 1.6.0 milestone on Dec 17, 2024
  2. Ocramius commented on Dec 10, 2025

    @Ocramius
    MemberAuthor

    We may need https://www.php.net/manual/en/function.gc-status.php for this - it may give us information on anything not GC'd?

    I couldn't get a really useful example out of it, but only tried for a couple minutes:

    <?php
    
    $iterations = 11111;
    
    class Leaky {
        public array $vals = [];
    }
    
    class BackReference {
        public function __construct(
            public readonly Leaky $backReference,
            public readonly int $counter
        ) {}
    }
    
    $leaky = new Leaky();
    
    var_dump(gc_status()['collected']);
    
    for ($i = 0; $i < $iterations; $i += 1) {
        $leaky->vals[] = new BackReference($leaky, $i);
    }
    
    var_dump(gc_status()['collected']);
    
    (function () use ($iterations) {
        $notLeaky = new Leaky();
        
        for ($i = 0; $i < $iterations; $i += 1) {
            $notLeaky->vals[] = new BackReference($notLeaky, $i);
        }
    })();
    
    var_dump(gc_status());
    
    gc_collect_cycles();
    
    var_dump(gc_status());

    Produces:

    int(0)
    int(0)
    array(4) {
      ["runs"]=>
      int(1)
      ["collected"]=>
      int(0)
      ["threshold"]=>
      int(20001)
      ["roots"]=>
      int(12225)
    }
    array(4) {
      ["runs"]=>
      int(2)
      ["collected"]=>
      int(11113)
      ["threshold"]=>
      int(20001)
      ["roots"]=>
      int(0)
    }
    

    I wonder if we can reliably count the collected counter after multiple test executions, and base ourselves on it?

  3. Ocramius commented on Dec 10, 2025

    @Ocramius
    MemberAuthor

    Thinking out loud:

    gc_collect_cycles();
    $before = measure_allocated(gc_status());
    
    run("first run", $test);
    
    gc_collect_cycles();
    $run1 = measure_allocated(gc_status());
    
    run("second run", $test);
    
    gc_collect_cycles();
    $run2 = measure_allocated(gc_status());
    
    assert(($run2 - $run1) === ($run1 - $before)); 

    Also being discussed in https://discord.com/channels/1090672946370052166/1091081297759309926/1448347506755895446 ( https://discord.gg/wp6sAjJR )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions