优化清理速度并修复内存泄漏

This commit is contained in:
markjiang 2019-07-24 15:39:18 +08:00 committed by Andy Pan
parent fc48d32604
commit 21a109c7f0
1 changed files with 20 additions and 13 deletions

31
pool.go
View File

@ -68,6 +68,7 @@ func (p *Pool) periodicallyPurge() {
heartbeat := time.NewTicker(p.expiryDuration)
defer heartbeat.Stop()
var purgeWorkers []*Worker
for range heartbeat.C {
if CLOSED == atomic.LoadInt32(&p.release) {
break
@ -75,23 +76,29 @@ func (p *Pool) periodicallyPurge() {
currentTime := time.Now()
p.lock.Lock()
idleWorkers := p.workers
n := -1
for i, w := range idleWorkers {
if currentTime.Sub(w.recycleTime) <= p.expiryDuration {
break
n := len(idleWorkers)
i := 0
for i < n && currentTime.Sub(idleWorkers[i].recycleTime) > p.expiryDuration {
i++
}
n = i
w.task <- nil
purgeWorkers = append(purgeWorkers[:0], idleWorkers[:i]...)
if i > 0 {
m := copy(idleWorkers, idleWorkers[i:])
for i = m; i < n; i++ {
idleWorkers[i] = nil
}
if n > -1 {
if n >= len(idleWorkers)-1 {
p.workers = idleWorkers[:0]
} else {
p.workers = idleWorkers[n+1:]
}
p.workers = idleWorkers[:m]
}
p.lock.Unlock()
// Notify obsolete workers to stop.
// This notification must be outside the p.lock, since w.task
// may be blocking and may consume a lot of time if many workers
// are located on non-local CPUs.
for i, w := range purgeWorkers {
w.task <- nil
purgeWorkers[i] = nil
}
}
}