function EntityFieldValueTraitTest::testMemoryReclamationAfterFieldAccess

Same name and namespace in other branches
  1. main core/tests/Drupal/KernelTests/Core/Entity/EntityFieldValueTraitTest.php \Drupal\KernelTests\Core\Entity\EntityFieldValueTraitTest::testMemoryReclamationAfterFieldAccess()

Tests memory reclamation after field access.

Verifies that loading entities one at a time with proper cache reset does not leak memory. Uses a warmup phase to stabilize one-time allocations, then measures growth over a second batch of entities.

Regression test for memory leaks described in:

File

core/tests/Drupal/KernelTests/Core/Entity/EntityFieldValueTraitTest.php, line 179

Class

EntityFieldValueTraitTest
Tests the EntityFieldValueTrait.

Namespace

Drupal\KernelTests\Core\Entity

Code

public function testMemoryReclamationAfterFieldAccess() : void {
  $total = 200;
  for ($i = 0; $i < $total; $i++) {
    User::create([
      'name' => "user{$i}",
      'mail' => "user{$i}@example.com",
      'status' => 1,
    ])->save();
  }
  $storage = \Drupal::entityTypeManager()->getStorage('user');
  $uids = array_values($storage->getQuery()
    ->accessCheck(FALSE)
    ->execute());
  // Warmup: process first batch to stabilize one-time allocations
  // (autoloader, internal caches, buffers).
  $warmup_count = 50;
  for ($i = 0; $i < $warmup_count && $i < count($uids); $i++) {
    $account = $storage->load($uids[$i]);
    $this->getFieldValue($account, 'name', 'value');
    $storage->resetCache([
      $uids[$i],
    ]);
  }
  gc_collect_cycles();
  $memory_after_warmup = memory_get_usage();
  // Process remaining entities and measure growth.
  for ($i = $warmup_count; $i < count($uids); $i++) {
    $account = $storage->load($uids[$i]);
    $this->getFieldValue($account, 'name', 'value');
    $storage->resetCache([
      $uids[$i],
    ]);
  }
  gc_collect_cycles();
  $memory_after_all = memory_get_usage();
  // With proper cleanup, processing 150 additional entities should not
  // grow memory significantly. A leak (e.g. retained FieldItemList
  // references) would show ~2-5KB per entity, easily exceeding 100KB.
  $this->assertLessThan(100 * 1024, $memory_after_all - $memory_after_warmup);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.