Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
1.2.0, 1.3.0, 1.2.2, 1.2.3, 1.3.2, 1.3.1
-
None
Description
received mail :
@
Inside org/mariadb/jdbc/internal/failover/AbstractMastersListener.java you have:
scheduledFailover = Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay
scheduledFailover being the future from the dynamically constructed pool. Unfortunately in java.util.concurrent.ThreadPoolExecutor (and in this case the extending class ScheduledThreadPoolExecutor) there is what I would call a defect around garbage collection. The inner class of ThreadPoolExecutor "Worker" (which is used to keep the thread alive and accept tasks) is not static. And thus once a thread has started a reference is maintained to the parent ThreadPoolExecutor, preventing the thread and the pool from ever being collected unless a .shutdown() is invoked. I say this is a defect in java because Doug L. did override the finalizer with a "shutdown()" call inside, so it seems like this was not the desired behavior, but sadly that wont be invoked once any threads start....btw this is still the case in the latest version of java.
The end result is that these threads, and ThreadPoolExecutors are NEVER collected. We have seen servers with > 300k threads due to this defect.
Some possible solutions (in order of my least preferable to what I think would be most preferable....personally):
- Your scheduled task could have a reference to the scheduler and could invoke .shutdown() after it has completed its work
- You could use a parent pool with a better start, shutdown lifecycle..one which can possibly reuse threads like a pool is typically designed to (this would be my preference)
- You could choose to use a better thread pool...