Skip to content

Large, long-lived arrays significantly impact cycle GC performance #6781

@dktapps

Description

@dktapps

Problem description

PM has large, long-lived arrays in a few different places. RuntimeBlockStateRegistry is the worst offender, but there are many others.

Because of the way PHP's GC works, the owners of these arrays almost always wind up in the GC root buffer, and PHP spends a significant amount of CPU time each GC run checking if any cycles were introduced to those arrays.

This is really problematic because of the huge performance impact it causes. An experimental patch using an extension to have the GC ignore objects containing large arrays produced a 5x improvement to GC performance.

The technicals of this issue are described in more detail here: php/php-src#19608

Proposed solution

It's not too clear what the solution to this may be yet. Currently I'm leaning towards a NonCollectableArray<K, V> class, which would wrap a regular array.

There are a couple of ways to avoid having a NonCollectableArray scanned for GC:

  1. use an extension like https://github.com/dktapps/ext-gcignore
  2. make a static array of arrays, and reference the correct array using spl_object_id(), instead of directly as an object field - this would break the dependency chain so that GC doesn't see the array(s) in connection with the target object

Alternative solutions or workarounds

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions