New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
php 8 - exit() takes a very long time to send response #10620
Comments
I'll take a look today. Could be coincidence, but 10 minutes is equal to 600 seconds, which is your time limit. I wonder if it exits because of the time limit and doesn't actually finish... |
Hi Niels, thanks for the promptness! I ran with lower time limit, but it didn't end any sooner. Let me know if I can help with anything else. Best, |
Preliminary testing shows that it's the cleaning up of the XML objects taking a lot of time. |
I profiled it with Callgrind. |
It makes sense. One additional info, though: Just loading the XML file doesn't cause the problem. It only happens when the nodes are fetched (json_encode($p)). My guess is that the XML module leaves all the allocated elements to be freed in the end. Question: since the script is terminating is it necessary to free them, won't the whole process' memory be deallocated by the OS? |
Yeah, I'm afraid the freeing problem is more a libxml2 problem than a PHP problem...
If you're using a single process PHP instance (for example on CLI), then yes you are right. You don't strictly need to free the data in that case, but that is only true for your specific workload here. If it's important to just exit quickly I can give you a hack for posix systems to just forcibly kill the process. On posix systems you could change the exit line to: echo( "Done, $cnt programs loaded" );
posix_kill(posix_getpid(), 9); However, I just noticed you're on Windows, so I don't know what we can do in this case... |
Got it, thanks for the explanation. Once again, thanks for your time. |
I dug into this more, although the performance of 7.4 & 8.1 is now the same, there is still something strange for 8.2 and above. I noticed that commit allocates more memory because every function now gets a mapped pointer, so there are more calls to Lines 1939 to 1953 in f5f44bb
I noticed a large allocation that did not happen prior to that commit: It seems we hit some sort of "unoptimal heap layout" ? I'm not sure. Normally this isn't a problem but for CLI scripts this is noticeable... |
No, I wasn't aware of such an issue. Does using |
Note that this uses the system allocator (1 is passed to persistent), so this is glibc malloc behaviour.
Avoiding the ptr map allocations altogether fixes the issue. |
Ah, I didn't realize this was an issue with the system allocator. TBH |
I also haven't really looked too deep into glibc's malloc, or its optimizations. From what I understand a different code path is taken when the requested size is bigger than a page, which is why I saw the problem when allocating 32KiB but not 4KiB.
Yes. |
Does this allocation happen at a particular time? E.g. after a lot of fragmentation from libxml? I'm not sure whether libxml uses zend_alloc or the system allocator. I suppose we could use |
Startup, when functions are registered for assigning the runtime cache pointer.
libxml only comes into action afterwards. I checked it, and as the document in the reproducer is only parsed and no manipulations happen there is almost no chance for fragmentation.
System allocator (unfortunately)
Yeah, I agree. I also think that even if we magically fix this, that other allocations can just screw us over again. I'm just very surprised that it is actually quite a noticeable slowdown.
No worries! |
Code
Description
For some reason the php opening line is correct, it breaks the report, so I inserted a space after <
This snipet of code takes around 15 seconds to execute and get to the exit() line. Existing, however, takes 10minutes, until the response is sent. The input file (epg.xml) has around 330,000 nodes. The actual code inside the foreach() loop doesn't realy matters much.
Tested with 8.1.14 and 8.2.3 - Same result on both.
Executing the same code with php 7.4.28 works fine, taking around 15 seconds to execute and spit out the response.
Relevant php configs : max_memory= 256M
Test environment: laptop HP, i7 8th Gen, 32GB RAM, 2TB nVme, Windows 11 PRO - 64 bits
The input file (epg.xml) is provided gz compressed.
epg.xml.gz
PHP Version
8.2.3
Operating System
Windos 11 64bits
The text was updated successfully, but these errors were encountered: