Weird issue... it seems to be related to PHP's garbage collector not working properly in circular references -- http://www.alexatnet.com/content/optimize-php-memory-usage-eliminate-cir...

It's a problem I can't reproduce on my local, but it happend on my dev server -- memory kept leaking when using entity_metadata_wrppaer() inside scripts I execute with Drush, iterating over thousands of entities.

Attached patch clears the $wrapper->cache, resulting with clearing the memory.

Comments

fago’s picture

But clear() only gets called when something is changed? So it won't be cleared automatically? Perhaps we should just add a public reset() method for clearing caches?

Afaik, the problem is 5.2 only. So upgrading to 5.3 should solve it too.

amitaibu’s picture

> But clear() only gets called when something is changed?

Indeed, in my script I had to manually call it. We can't add it into __destructor() as it won't be called (chicken & egg)

fubhy’s picture

Status: Needs review » Needs work
+++ b/includes/entity.wrapper.incundefined
@@ -167,6 +167,10 @@ abstract class EntityMetadataWrapper {
+    // Clear the cache, so we won't have any child object still ¶
+    // referenced, so later PHP's garbage collector will destruct the ¶

Patch works... It's up to fago to decide whether we want to implement it like this. However, if we choose to use this patch we should remove the trailing whitespaces in the first two lines of the comment :).

fago’s picture

Hm, if we do that I don't think the cache would help a lot. Anyway, I've been thinking whether it's necessary to have that kind of cache at all. Maybe we should do some benchmarks on it, e.g. with using some Rules and other common access patterns?

fago’s picture

Reasons for removing the cache:

  • Less complexity.
  • No circular dependencies, gc++.
  • No possible weird issues when using language() which adds a state to the wrapper object combined with the cache.
alemadlei’s picture

This thread is quite old, but I'm interested if there was any discussion regarding this.

I'm experiencing this problem where using entity_metadata_wrapper on around 200000 items is using too much memory. I had to break down into smaller pieces by separate process in order to keep memory in check.

I will try the patch, but I would really appreciate if someone could point me to an update on this. Using version 7.x-1.6 on my site.

Regards,

joelpittet’s picture

Issue summary: View changes

public reset() would be nice. I noticed after a commerce_order save that the cache was stale on the EMW.

joelpittet’s picture

data was correct but cache was stale on the number of commerce_line_items field items on the order.

joelpittet’s picture

Status: Needs work » Needs review
StatusFileSize
new786 bytes

Yup adding a reset() and clearing the cache fixes my issue.

joelpittet’s picture

I just put the patch up to test something out but I'm a big +1 to #5

Scott Robertson’s picture

Status: Needs review » Reviewed & tested by the community

Going to RTBC this as I ran into similar caching issues with EMW. This was in PHP 5.6, so not just a problem in 5.2.

If there are no plans to remove the cache as mentioned in #5, this patch at least makes it possible to manually clear the cache when you're having problems.

fago’s picture

Status: Reviewed & tested by the community » Needs work

Yep, adding a public reset is fine, however this patch also adds the reset we do not want / can do without performance benchmarks. So setting to needs work.

Chris Charlton’s picture

FWIW, I still desire this feature.

mpaler’s picture

StatusFileSize
new812 bytes

Here's the patch with the modification recommended by fago.

joelpittet’s picture

Title: $wrapper->clear() should unset $wrapper->cache » $wrapper->reset() should unset $wrapper->cache
Status: Needs work » Reviewed & tested by the community

That's a bit of progress on the issue, I'll take it.