2013-05-09 23 views
6

Ruby'de bir sınıf için ayrılmış belleğin boyutunu görmek için bir yöntem var mı?Sınıfın bayt cinsinden boyutu

Özel bir sınıf oluşturdum ve belleğindeki boyutunu bilmek istiyorum. Yani C içinde sizeof() benzerliği ile bir işlev var mı?

Sadece bu kadar

test = MyClass.new 

gibi yeni bir sınıf başlatmak için çalışıyor ve hafıza tahsis edilmiş sınıfın büyüklüğü yazdırmak için bir yöntem bulmaya çalışıyorum.

Bu yakutta mümkün mü?

+0

Bu soru için en az iki sorun var: 1) Bir nesnenin tüm özellikleri de diğer sınıfların nesneleridir, bu nedenle bunların dahil olup olmadığının açık olması gerekir. 2) Örnek değişkenlerin sayısı ve türleri Ruby'de dinamiktir, bu yüzden bir sınıfın bellek boyutu gibi bir şey yoktur. Bununla birlikte, teoride şu anda bir nesneye tahsis edilmiş olan belleği ölçebilirsiniz (şu anda nasıl yapamayacağımı veya Ruby'nin bunu yapmasına izin vermiş olmamakla birlikte). –

cevap

6

bir nesnenin bellek boyutu uygulamaya bağlıdır C

ile aynı şekilde, bir sınıf boyutunu hesaplar hiçbir dil özelliği yoktur. Temel sınıf nesnesinin uygulanmasına bağlıdır. Kullanılan belleği tahmin etmek de kolay değildir. Örneğin, dizeler kısasa bir RString yapısına yerleştirilebilir, ancak uzunsa (Never create Ruby strings longer than 23 characters) yığında saklanabilirler.

bazı nesneler tarafından alınan bellek farklı yakut uygulamaları için tablo edilmiştir: isteğe bağlı olarak ilave örnek değişkenleri eklemek mümkündür çünkü Memory footprint of objects in Ruby 1.8, EE, 1.9, and OCaml

Son olarak, nesne boyut, aynı sınıftan iki nesne ile daha da farklı olabilir, hardcoding olmadan örnek değişkenleri bulunur. Örneğin, instance_variable_get ve


Eğer MRG yakut 1.9.2+ kullanırsanız instance_variable_set görüyorsun, o nesnenin yalnızca bir kısmı bakıyor uyarılmalıdır (deneyebilirsiniz bir metot vardır, bundan açıktır tamsayılar ve dizeleri boyutu sıfır var görünüyor gerçeği):

irb(main):176:0> require 'objspace' 
=> true 
irb(main):176:0> ObjectSpace.memsize_of(134) 
=> 0 
irb(main):177:0> ObjectSpace.memsize_of("asdf") 
=> 0 
irb(main):178:0> ObjectSpace.memsize_of({a: 4}) 
=> 184 
irb(main):179:0> ObjectSpace.memsize_of({a: 4, b: 5}) 
=> 232 
irb(main):180:0> ObjectSpace.memsize_of(/a/.match("a")) 
=> 80 

Ayrıca memsize_of_all deneyebilirsiniz (bu bütün tercüman bellek kullanımına bakar unutmayın ve bir değişken üzerine yazarak eski bir kopyasını silmek için görünmüyor hemen):

irb(main):190:0> ObjectSpace.memsize_of_all 
=> 4190347 
irb(main):191:0> asdf = 4 
=> 4 
irb(main):192:0> ObjectSpace.memsize_of_all 
=> 4201350 
irb(main):193:0> asdf = 4 
=> 4 
irb(main):194:0> ObjectSpace.memsize_of_all 
=> 4212353 
irb(main):195:0> asdf = 4.5 
=> 4.5 
irb(main):196:0> ObjectSpace.memsize_of_all 
=> 4223596 
irb(main):197:0> asdf = "a" 
=> "a" 
irb(main):198:0> ObjectSpace.memsize_of_all 
=> 4234879 

Ruby yorumlayıcısının çöp toplama işlemini gerçekleştireceği zaman garanti verilmediğinden çok dikkatli olmalısınız. Bunu test ve deney için kullanabilseniz de, bunun üretimde KULLANILMAMASI tavsiye edilir!

+0

Buna ne dersin o zaman. Sınıfların X sayısını başlatmak ve daha sonra ruby ​​yorumlayıcısının bellek kullanımını önce ve sonra çekmek mümkün mü? Her bir soketin kendi iş parçacığımdaki sınıflarımdan 3 tanesinin tek bir kopyasını alacağı bir sorunla karşılaşıyorum (paketlerin taşınması için ve böyle). Bu nedenle, her bir dersimin 30 örneği olan 10 bağlantı varsa. Bunun temel bir tasarım problemi olup olmadığını merak ediyordum ve paketlerimi nasıl ele alacağımı/düşünmem gerektiğini veya 3 sınıfın minik bellek kullanımıyla sonuçlanacağını düşünürdüm. –

+0

Bu ilginç sonuçlar verir, sadece çalıştırdığımda 'ObjectSpace.memsize_of_all' koyarken '1180174' olarak tahmin edilen bir değer elde ettim ama ben çalıştırdığımda (0..1000) .each do | i |; tPush PacketParser.new i; end 've' ObjectSpace koyar.memsize_of_all '920578' aldım, bu da benim sınıflarımın 3000'in üzerinde başlatmadan daha az. Çöp işlemenin yanı sıra burada eksik olduğum bir şey mi var? Aslında 3000 sınıf oluşturmuyor, sadece 3 sınıfı veya bir şeyi referans alıyor musunuz? –

+0

cevap vermem imkansızdır - her yinelemeyi kontrol edebilirsiniz (belki bazı iterasyonlarda ani düşüşleri göreceksiniz). Yukarıdaki nesnede sadece nesneleriniz için bellek ayırmanın değil, farkında olmalısınız. PacketParser yapıcısı ve t.push yöntemi, bellek kullanımını (geçici olarak) artıran yerel değişkenleri de ayırabilir. – ronalchn

İlgili konular