-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Fix GH-8646: Memory leak PHP FPM 8.1 #10783
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test looks very nice and reliable 🙂 LGTM. Let's verify this by Dmitry, hopefully our analysis makes sense.
By design It seems, that you've found a simple way to fix this by calling I would just propose to move the fixing code into |
Thank you very much for the review!
I will do that after work tonight. Thanks! |
Fixes phpGH-8646 See php#8646 for thorough discussion. Interned strings that hold class entries can get a corresponding slot in map_ptr for the CE cache. map_ptr works like a bump allocator: there is a counter which increases to allocate the next slot in the map. For class name strings in non-opcache we have: - on startup: permanent + interned - on request: interned For class name strings in opcache we have: - on startup: permanent + interned - on request: either not interned at all, which we can ignore because they won't get a CE cache entry or they were already permanent + interned or we get a new permanent + interned string in the opcache persistence code Notice that the map_ptr layout always has the permanent strings first, and the request strings after. In non-opcache, a request string may get a slot in map_ptr, and that interned request string gets destroyed at the end of the request. The corresponding map_ptr slot can thereafter never be used again. This causes map_ptr to keep reallocating to larger and larger sizes. We solve it as follows: We can check whether we had any interned request strings, which only happens in non-opcache. If we have any, we reset map_ptr to the last permanent string. We can't lose any permanent strings because of map_ptr's layout.
Moved the code as requested :) |
Fixes GH-8646
See #8646 for thorough discussion.
/cc @iluuu1994
Interned strings that hold class entries can get a corresponding slot in map_ptr for the CE cache. map_ptr works like a bump allocator: there is a counter which increases to allocate the next slot in the map.
For class name strings in non-opcache we have:
For class name strings in opcache we have:
Notice that the map_ptr layout always has the permanent strings first, and the request strings after. In non-opcache, a request string may get a slot in map_ptr, and that interned request string gets destroyed at the end of the request. The corresponding map_ptr slot can thereafter never be used again. This causes map_ptr to keep reallocating to larger and larger sizes.
We solve it as follows:
We can check whether we had any interned request strings, which only happens in non-opcache. If we have any, we reset map_ptr to the last permanent string. We can't lose any permanent strings because of map_ptr's layout.