Skip to main content

Drupal 9: PHP Memory leak when loading and looping through multiple nodes or entities

In Drupal entities and nodes are statically cached when they’re loaded. Load enough of them and the static cache will fill up the available memory. This is how you reset or unset your php memory in order to avoid nasty memory leaks.

$memory_cache = \Drupal::service('entity.memory_cache');
$entity_storage = \Drupal::entityTypeManager()->getStorage('node');


$nids = \Drupal::entityQuery('node')
  ->condition('type', 'issues')
  ->execute();

$chunks = array_chunk($nids, 100);

foreach ($chunks as $chunk) {
  $entities = $entity_storage->loadMultiple($chunk);

  foreach ($entities as $entity) {
    // Do your stuff with the node/other entities.
  }

  $memory_cache->deleteAll();
}

Or with custom entities

$dateFrom = strtotime($dateFrom) + (86400 * 3);
$dateTo = strtotime($dateTo);

$entity_type = 'tests';
$bundle = 'pixelthis';
$entity = \Drupal::entityTypeManager()->getStorage($entity_type);
$query = $entity->getQuery();
$query->condition('type', $bundle);
$query->condition('created', [$dateFrom, $dateTo], 'BETWEEN');
$query->sort('created', 'ASC');

$ids = $query->execute();

if (!is_array($ids) || empty($ids)) return;

$chunks = array_chunk($ids, 100);
$agData = [];
//ksm(count($ids));
foreach ($chunks as $chunk) {

$entities = $entity->loadMultiple($chunk);

foreach ($entities as $cEntity) {

$created = $cEntity->get('created')->value;
$agData[$created]['day_total'][] = $cEntity->get('field_day_total')->value;
$agData[$created]['new_total_distinct'][] = $cEntity->get('field_new_total_distinct')->value;
$agData[$created]['new_total_daily'][] = $cEntity->get('field_new_total_daily')->value;
}

$entity->resetCache($chunk);
//var_dump("Mem usage: " . convertByteSize(memory_get_usage(true)) . "\n<br>");

}

 

best practices