ID: 47525 User updated by: rodricg at sellingsource dot com Reported By: rodricg at sellingsource dot com Status: Bogus Bug Type: Scripting Engine problem Operating System: linux PHP Version: 5.2.9 New Comment:
IMHO __call is breaking copy-on-write semantics. At the very least it could be said that memory utilization with __call is less efficient than without it. Despite setting of USE_ZEND_ALLOC. USE_ZEND_ALLOC=1 valgrind php -n -d memory_limit=1024M b.php 100 getStr malloc/free: 15,018 allocs, 13,296 frees, 4,253,597 bytes allocated. USE_ZEND_ALLOC=1 valgrind php -n -d memory_limit=1024M b.php 100 magic malloc/free: 15,118 allocs, 13,396 frees, 109,111,199 bytes allocated. USE_ZEND_ALLOC=0 valgrind php -n -d memory_limit=1024M b.php 100 getStr malloc/free: 18,181 allocs, 16,459 frees, 4,407,683 bytes allocated. USE_ZEND_ALLOC=0 valgrind php -n -d memory_limit=1024M b.php 100 magic malloc/free: 18,981 allocs, 17,259 frees, 104,439,576 bytes allocated. http://bugs.pastebin.com/f754ba8cd Previous Comments: ------------------------------------------------------------------------ [2009-05-02 03:01:24] [email protected] Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ and the instructions on how to report a bug at http://bugs.php.net/how-to-report.php This is a side-effect of the Zend memory manager. If you run the script with PHP build with --enable-debug and like this: # USE_ZEND_ALLOC=0 php test.php new A(): 8,280 $a->str: 8,280 $a->getStr(): 8,280 $a->magic(): 8,280 You see that there is no leak or unnecessary "copying" anywhere. ------------------------------------------------------------------------ [2009-02-28 01:56:43] rodricg at sellingsource dot com Description: ------------ Values returned from the magic __call method are copied immediately resulting in increased memory usage. Reproduce code: --------------- <?php function mem($msg='') { echo ($msg ? $msg.": " : '').number_format(memory_get_usage(1))."\n"; } class A { public $str; public function __construct() { $this->str = str_repeat("a", 1000000); } public function __call($m, $a) {return $this->str;} public function getStr() {return $this->str;} } $a = new A(); mem('new A()'); $b = $a->str; mem('$a->str'); $c = $a->getStr(); mem('$a->getStr()'); $d = $a->magic(); mem('$a->magic()'); ?> Expected result: ---------------- new A(): 1,310,720 $a->str: 1,310,720 $a->getStr(): 1,310,720 $a->magic(): 1,310,720 Actual result: -------------- new A(): 1,310,720 $a->str: 1,310,720 $a->getStr(): 1,310,720 $a->magic(): 2,359,296 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=47525&edit=1
