When creating many processes concurrently under load, it's possible to exhaust the 64 EpollEvents in the queue and end up with threads blocked waiting for one to free up. If such a thread gets interrupted, it ends up leaking the process as a zombie.
I ran the jmh microbenchmark before and after this change to check the allocation rate and found no measurable difference. There was also no measurable difference in performance.
Added an EpollEvent field to LinuxProcess
This way each process has its own event instance that can be used (and reused) whenever the processing thread needs to reconfigure the epoll registration
Since each write to stdin requires its own EPOLLONESHOT event, having a reusable EpollEvent avoids allocation churn
Removed the eventPool in ProcessEpoll and updated it to use the process's EpollEvent when necessary
Updated wording for a few RuntimeExceptions to make their messages a little more consistent, and added errno values to some that weren't including them to assist with debugging/analysis
When creating many processes concurrently under load, it's possible to exhaust the 64
EpollEvent
s in the queue and end up with threads blocked waiting for one to free up. If such a thread gets interrupted, it ends up leaking the process as a zombie.I ran the jmh microbenchmark before and after this change to check the allocation rate and found no measurable difference. There was also no measurable difference in performance.
EpollEvent
field toLinuxProcess
epoll
registrationstdin
requires its ownEPOLLONESHOT
event, having a reusableEpollEvent
avoids allocation churneventPool
inProcessEpoll
and updated it to use the process'sEpollEvent
when necessaryRuntimeException
s to make their messages a little more consistent, and addederrno
values to some that weren't including them to assist with debugging/analysis