The garbage you can’t dispose of…

Looks like Jeff’s made an unpleasant discovery while exploring Rephlux and PHP memory usage in WACT.

Adding the following to WACT’s unit test suit (which basically executes everything WACT has);


foreach (array_keys($GLOBALS) as $key) {
echo "$key=" . strlen(serialize($GLOBALS[$key]));
}

This shows up: ‘_PEAR_destructor_object_list=146270′

To support this gem, PEAR puts a reference to every object instance ever instantiated that inherits from PEAR into the global variable _PEAR_destructor_object_list. There the object stays until the deconstruction shutdown function is called. This reference prevents garbage collection of any of objects inheriting from PEAR or the memory they reference during the lifetime of the script. And it does this for no good reason at all.

The file in question is PEAR.php. And in fact I’m the guilty party for having extended from it in XML_HTMLSax (now gone with latest 3.0.0 release).

My guess is there are other projects like PhpDocumentor and anyone doing “build-like” tasks via cron, using PEAR code that could also do without donating memory to no good purpose. For PHP web applications it’s likely less of an issue but it’s still wasted overhead.

Perhaps while PEAR package developers consider where to go with PHP5 support and breaking backwards compatibility, another mission could modifying any class that extends PEAR.php directly. Better yet cut down PEAR.php itself to be a single class with a single method – isError() – which is about the only thing anyone is really using anyway.

(update) – make that two methods – isError and raiseError – typing too fast…

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Joshua Eichorn

    Thats why no one extends from the PEAR class unless they need destructors. In fact most people try to not even include PEAR.inc until they are actually raising an error.

  • CT

    I have found that it is very easy to code PEAR compatible classes that are a fraction the size of the PEAR ones by only implementing the methods that I use. Like you I only use isError and raiseError. The improved Error class would probably be under 1k.

    The same with PEAR DB. It is posible to create a class that is under 5k that implements the methods, for a single DB type, used by 90% of PEAR DB users (connect, query, limitQuery, nextId, isError, getMessage and result: fetchRow, numRows, isError, getMessage). Compare that with 34k for DB.php, 30k for DB/mysql.php, and 62k for DB/common.php. The bloat and waste in PEAR is amazing. And lose the wasteful factory pattern.

    The great things about compatable classes is that other programmers already know the interface and you can always switch back later if necessary. Maybe you WACTies can code up a set of PEAR compatable classes that are not so bloated and wasteful.

  • http://www.phppatterns.com HarryF

    Hi Joshua

    Thats why no one extends from the PEAR class unless they need destructors. In fact most people try to not even include PEAR.inc until they are actually raising an error.

    Yes and no. Seems like, for the most part, PEAR developers avoid it but there are a couple of exceptions which are getting widely used, like DB_Common (all the concrete DB implementations extend this) in PEAR::DB and XML_Parser (alot of the XML related packages extend XML_Parser and thereby extend PEAR). Neither of these seems to actually use the destructor functionality.

    Maybe you WACTies can code up a set of PEAR compatable classes that are not so bloated and wasteful.

    Problem then is you get into supporting your own version – more work in other words. Generally it’s not critical anyway – this is more a special case where it was.

  • Alan Knowles

    i’m not sure DB_Common is a big issue – you are probably likely to only use 1 instance of it. XML_Parser is a bit more of a nightmare..

    This is a bug in PEAR – the _PEAR destructor should not be defined.. – hence the array should not be created unless there is a real destructor…. Have you filed a bug :)

  • CT

    “Problem then is you get into supporting your own version – more work in other words. Generally it’s not critical anyway – this is more a special case where it was.”

    But Wact did its own DAOs. Why not make them PEAR DB API compatable?

    “i’m not sure DB_Common is a big issue – you are probably likely to only use 1 instance of it. XML_Parser is a bit more of a nightmare..”

    They both are. Too many includes; too large includes. Luckily PHP5′s PDO and XML will solve both these problems.

  • Lukas

    this bug is fixed now. a reference is now only stored if a PEAR destructor method is defined. So this will only affect those classes that rely on PEAR’s destructor emulation.

  • http://www.phppatterns.com HarryF

    Hi Lukas,

    this bug is fixed now. a reference is now only stored if a PEAR destructor method is defined. So this will only affect those classes that rely on PEAR’s destructor emulation.

    Many thanks for the info and for fixing it.

    All the best,

    Harry