Though profiling our application I found a a quite strange memory usage because of the ob_start()#) functionality. We do work with ob_start()#) a reasonable amount to defer production of data, that is a common thing in most applications. What seemed to be unusual is of which 16 calls to help ob_start()#) in place chewing through pretty much 700kb of ram, given that the results being buffered not often exceeds 1-2kb, i thought this was quite unusual.
I started thinking about the C code on the ob_start()#) functionality and found this interesting chunk of code inside php_start_ob_buffer()
initial_size = 40*1024;
block_size = 10*1024;
Which directs PHP to help pre-allocate 40kb of data for every single ob_start()#) call and once this proves for being insufficient, increase by 10kb everytime. Ouch!
PHP does assist you to say how considerably memory ob_start()#) incorporate the use of, via 2nd parameter towards function. However, when you exceed that measurement, PHP will instantly flush the seized data to tv screen, which means that if you are really effective in predicting your buffer sizes or widely overestimate, there is a risk which the data will possibly be dumped to tv screen by PHP begin using this option.
Since i am not fabulous at guessing, I’ve decided to manufacture a small, backwards works tweak to PHP’s value that allow options of custom buffer sizes, but encourage the buffer size for being increased if the 1st buffer size proves for being insufficient, ensuring which the data can possibly be safely buffered. This functionality is implemented by using a change (view patch below) towards 1st parameter on the ob_start()#) functionality, which normally is needed to provide this callback function. While using the patch in area the parameter, generally is a number, which defines the required buffer size. While using the patch, ob_start(1024) shows that the 1kb buffer need to be used and only when it’s exceed keep allocating 1kb each time to allow intended for additional data for being stored. This solution does mean you should not use custom, resizable buffer sizes that has a callback function, but it surely does provider some sort of backwards (PHP API prudent) compatible strategy for implementing the efficiency in PHP 5. 3 and 5. 3.
Here is a simple before & after code sample:
PHP:
will print out 0, since buffer is over the limit and is flushed to output
PHP:
will print 1500, buffer was exceeded and then increased, making it possible for data to remain in the buffer
CODE:
Index: main/output.c
===================================================================
--- main/output.c (revision 320624)
+++ main/output.c (working copy)
@@ -155,10 +155,14 @@
initial_size = (chunk_size*3/2);
block_size = chunk_size/2;
} else {
- initial_size = 40*1024;
- block_size = 10*1024;