Dear all,
Problem
As mentioned here:
PHP: Fatal error: Allowed memory size of 134217728 bytes exhausted (CodeIgniter + XML-RPC)
and here
XML-RPC Server Memory Usage
and here
XML-RPC memory leak question..
Solution Explanation
I found a bug in XML-RPC library. It leads to extensive usage of memory. This happens when `XML-RPC` Server creates many instances of `XML_RPC_Values`. I investigate in this class and found that it `extends` `CI_Xmlrpc` class. This inheritance comes with high cost. One of the attributes of `CI_Xmlrpc` is:
$this->valid_parents = array('BOOLEAN' => array('VALUE'),
'I4' => array('VALUE'),
'INT' => array('VALUE'),
'STRING' => array('VALUE'),
'DOUBLE' => array('VALUE'),
'DATETIME.ISO8601' => array('VALUE'),
'BASE64' => array('VALUE'),
'ARRAY' => array('VALUE'),
'STRUCT' => array('VALUE'),
'PARAM' => array('PARAMS'),
'METHODNAME' => array('METHODCALL'),
'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
'MEMBER' => array('STRUCT'),
'NAME' => array('MEMBER'),
'DATA' => array('ARRAY'),
'FAULT' => array('METHODRESPONSE'),
'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT')
);
These creations of arrays happen for all instances of `XML_RPC_Values`! (Which is in my case 1300 instances of `XML_RPC_Values`) (Note also that it should be shared among all of these instances.)
However, class `XML_RPC_Values` is not supposed to extend `CI_XML_RPC`. No need for that. It uses only one member of `CI_XML_RPC` and that all.
The solution is to replace `XML_RPC_Values` with attached class.
Changes
- add a static attribute: `xmlrpcTypes` which is like the one in `CI_Xmlrpc`
- change refernces to `CI_Xmlrpc`->xmlrpcBoolean, `CI_Xmlrpc`->xmlrpcDouble, `CI_Xmlrpc`->xmlrpcString, `CI_Xmlrpc`->xmlrpcBase64 to their actual values since they are already known.
- remove `extends CI_Xmlrpc`
Results
Free up to 75% of memory.
Before:
16MB
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 35 bytes)
After:
4MB
xdebug_peak_memory_usage()= 4394704
Wawww!
Best Regards,
AbdulRahman AlOsaimy
