I have a rather large graph full with cyclic references in PHP memory. I was serialising the whole graph to store it in between requests. It worked well on PHP5.3, but now I upgraded to PHP5.5 and something strange is happening:
PHP / Apache crashes/exits suddenly during serialisation and chrome shows ERR_CONNECTION_RESET
There is no error in de PHP log nor is there anything in the Apache log in debug mode.
After quite a bit of debugging I've noticed that if I make the graph a little bit smaller it still works. However if I turn the data back on bit by bit there are very specific points where it fails if I reintroduce them. If I skip that specific point and introduce other data instead I can still continue.
not a memory problem
I've set a very high memory limit: memory_limit = 2048M
, and just before I introduce the data that crashes it memory_get_usage()
gives 26M and memory_get_peak_usage()
gives 41M, so there's plenty left.
not a time problem
It's probably not time related either as it is well within the timeout settings, and when it crashes it actually crashes sooner than how long it took to complete the last working serialisation.
too much cyclic references / loops?
The data I introduce that causes the crashing does nothing special in terms of objects. It's all the same kind of PHP objects (Nodes and Edges for simplicity). Also the relations directly surrounding the object I introduce don't tell me anything strange. One thing I'm thinking off is that once the 'problematic' data is introduced the way the serialize algorithm goes through all the objects changes, changing the traversal path and causing something to crash because... too deeply neested?
some other upper bound?
the other thing I can think off is that there is some other upper limit I'm reaching. Because the thing is: once I've found a 'problematic' piece of data that I can not turn back on without causing a crash, I can turn it back on if I turn some other parts off again first. So that doesn't seem to point to the data at all. But which limit? The maximum string length I've been able to squeeze out is 5.517.365 characters, which is a little over 5MB according to mb_strlen($string, '8bit')
. But sometimes the string is around 4 million characters and when I add a little bit back it crashes. That could still mean that that little bit of data caused some deeper/bigger parts of the graph to be serialised sooner on, thus internally hitting the same upper bound of something?
Does serialize() use something like a buffer or tmp file or should it really just use 'plain memory'?
any idea which other bounds I might be hitting? and/or which settings might solve it?