Thread 使用提醒:memory leak


#1

大概就是某人寫了一支程式叫我 debug …,程式類似長這樣子

WORKER = 8
works = []
QUEUE_SIZE = 500
queue = []
loop do
  if queue.length < QUEUE_SIZE
    queue << {something}
  end
  WORKER.times do |i|
    if !works[i] || !works[i].status
      if temp = queue.pop
        works[i] = Thread.new do
          ... # do temp
        end
      end
    end
  end
end

結構看似正常,上面塞然後生 Thread 去解,然後就 … 糟了,記憶體使用量會一直增長
這邊的 bug 全等於這邊所述

https://bugs.ruby-lang.org/issues/11174

原因猜測是 Thread 使用後,Ruby 會留下 Thread 的 header 並且沒有 free 掉,然後就噴了…

所以建議改成不要隨拋即用的 Thread,而是 loop 在 Thread 內,也就是不輕易拋棄的意思,類似

WORKER = 8
works = []
QUEUE_SIZE = 500
queue = []
WORKER.times do |i|
  works[i] = Thread.new do
    loop do
      if temp = queue.pop
        ... # do temp
      else
        sleep(0.001)
      end
    end
  end
end
loop do
  if queue.length < QUEUE_SIZE
    queue << {something}
  else
    sleep(0.001)
  end
end

的方式來完成即可,上面的 code 是最簡式,queue 請用 Queue 而非 array,Thread寫作這邊也有別的篇幅介紹就是了