9

I'm having an issue in Drupal 8 where I am unable to loop through a large amount of nodes without hitting memory limits. The products content type in the below example has ~6000 nodes. The memory limit is currently set to 512M and is not changeable.

I've tried unsetting the $node variable and clearing the entity cache in the loop without any success.

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

foreach ($nids as $nid) {
    $node = \Drupal\node\Entity\Node::load($nid);
    print $node->title->value;
}

The goal is to be able to iterate through all nodes of a content type without hitting memory limits.

5
  • And how did you clear the entity cache?
    – Berdir
    Commented Jun 1, 2016 at 16:41
  • Why don't you use a queue or some cron process? Doing a long time and memory consuming process is not recommended even there's an admin user or automated request waiting (you know, people than can wait).
    – sanzante
    Commented Jun 1, 2016 at 16:47
  • Clearing the cache with \Drupal::entityManager()->getViewBuilder('node')->resetCache(). Building a queue out seems a little extreme, this was possible in D7.
    – Xandor
    Commented Jun 1, 2016 at 17:25
  • Try to use xhprof or a similar tool to figure out where the memory is actually used. See stackoverflow.com/questions/255941/… for some ways to do that. Could be a bug somewhere. There might be some services that are keeping references to the objects, blind guess would be entity type manager/typed data manager. You can kill them completely with \Drupal::getContainer->set('service_id', NULL).
    – Berdir
    Commented Jun 1, 2016 at 19:53
  • No luck, tried where 'service_id' was 'entity.manager'
    – Xandor
    Commented Jun 3, 2016 at 15:26

1 Answer 1

6

I was able to get this to work by using the following command pulled from the deprecated node_load() function.

\Drupal::entityManager()->getStorage('node')->resetCache(array('NID'));

The fixed script would be:

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

foreach ($nids as $nid) {
    $node = \Drupal\node\Entity\Node::load($nid);
    print $node->title->value;
    \Drupal::entityManager()->getStorage('node')->resetCache(array($nid));
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.