0

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?

Flion
  • 10,468
  • 13
  • 48
  • 68
  • The 'cyclic' error leads me to believe that objects are referencing each other and vice-versa. Is there a parent/child relationship inside the object being serialized? – Michael Coxon Jan 28 '16 at 05:41
  • Also if possible can we see the schema of the object being serialized? – Michael Coxon Jan 28 '16 at 05:42
  • Yes there are a __lot__ of relationships back and forward between the objects but there is no cyclic 'error', PHP states [circular references inside the object will also be serialised](http://php.net/manual/en/function.serialize.php) .. and it indeed did so just fine. – Flion Jan 28 '16 at 05:46
  • @MichaelCoxon the schema is a typical graph. There are Nodes and Edges. Any node can be connected to any number of other nodes via an Edge. Thus each Node object contains an array of Edges, and each Edge contains both the Nodes it connects. – Flion Jan 28 '16 at 05:50

0 Answers0