2013-09-24 21 views
26

altı Sidekiq çalışanı var , JSON taraması. Bitiş noktasının veri kümesi boyutuna bağlı olarak 1 dakika ile 4 saat arasında tamamlanır. Özellikle, 4 saat süren uzun olanı seyrederken, hafızada çok az bir artış olduğunu görüyorum. Yine aynı işçi işlerini planlamak istiyorsanız kadarİşçiler işlerini bitirdikten sonra bellek ayrılmıyor Sidekiq

Bu bir sorun, değil. Bellek, Sidekiq sürecimden kurtulan Linux OOM Killer'e girene kadar tahsis edilmedi ve yığınlandı.

Bellek sızıntı? Ben ObjectSpace farklı nesnelerin sayısını izledi:

ObjectSpace.each_object.inject(Hash.new(0)) { |count, o| count[o.class] += 1 } 

gerçekten vb orada artış sağlamalarının seti, diziler, aynı, kısa artışlar Çöp Toplayıcı ve gc.stat[:count] anlatır tarafından süpürüldü olan kalır yok Ben de Çöp Toplayıcısı da çalışıyor.

işçi tamamlandıktan sonra bile, örneğin, [Done] günlüğünü alıyorum ve artık hiç kimse meşgul değil, bellek ayrılmıyor. Bunun nedenleri neler? Buna karşı bir şey yapabilir miyim? Bir finalizer yazınız mı?

TEK mevcut çözelti: Sidekiq işlemini yeniden başlatın.

Ben Ruby 2.0.0 am ve Yakut MR kullanın. I Yajl kullanmak JSON ayrıştırma için


, böylece bir Cı bağlayıcı. İhtiyacım var çünkü akan okuma ve yazmayı düzgün bir şekilde uygulayan tek hızlı JSON ayrıştırıcısı gibi görünüyor. Sidekiq yazdı

+1

JSON girişini ayrıştırmak için hangi mücevheri kullanıyorsunuz? C-uzantıları ile başka taşlar kullanıyor musunuz? Tanımlamanızdan (bellek kullanımı büyür, fakat Ruby nesnelerinin sayısı sabittir) bir C-uzantısıyla bir gemiden sızıntıya sahip olmanız gibi (örneğin, bir mücevher bir Ruby nesnesini depolamak için kullanılmayan bellek ayırıyorsa) ve asla serbest bırakmamak). – grumbler

+4

Ayrıca, bir nesneyi tekrar tekrar mutasyona soktuğunuz ve yeni nesneler tahsis etmeden boyutta büyümeye neden olduğunuz saf bir Ruby 'sızıntısı' olması da mümkündür. Örneğin, bir Ruby String'e tekrar tekrar eklemek, nesne sayınızı çarpmaksızın sürekli olarak daha fazla bellek tüketmesine neden olur. – grumbler

+1

@grumbler İyi bir nokta. Sorumu uzattım. Ben JSC ayrıştırma için Yajl kullanıyorum, bu gerçekten bir C bağlamasıdır. Bunu hiç düşünmemiştim. –

cevap

8

Mike Perham burada bu ele: http://www.mikeperham.com/2009/05/25/memory-hungry-ruby-daemons/

tl; dr sürümü: MRG geri bellek vermeyecektir, en Yapabileceğiniz yığın kontrol ve bu yapmaktır, Ruby Enterprise Edition önerilmiştir.

bunların hiçbirini yardımcı olduğunu bilmiyorum, ama bu durum - düz atın ağzından.

+1

Güzel İşaretçiler @digitalextremist +1 – Rohit

+1

Bu ilginç, teşekkürler :) –

+9

Eski iş parçacığı, biliyorum ama merak ediyorum Bunun hala Ruby 2.1 ve yeni GC için geçerli olup olmadığını biliyor musunuz? –