2013-05-09 29 views
6

有沒有一種方法可以查看ruby中類的分配內存的大小?以字節爲單位的類的大小

我已經構建了一個自定義類,我想知道它的大小在內存中。那麼在C中有一個類似sizeof()的函數嗎?

我只是試圖初始化一個新的類,像這樣

test = MyClass.new 

,並試圖找到打印出已分配到存儲類的大小的方法。

這甚至可能在紅寶石?

+0

這個問題至少有兩個問題:1)對象的所有屬性也是其他類的對象,所以你需要清楚它們是否包含在內。 2)實例變量的數量和類型在Ruby中是動態的,因此實際上並不存在類的內存大小。然而,理論上你可以測量當前分配給對象的內存(雖然我目前不知道如何,或者Ruby是否允許你這樣做)。 – 2013-05-09 07:27:26

回答

6

沒有語言特性,其計算以相同的方式爲C.

一類的大小的對象的存儲器大小是依賴於實現的。它取決於基類對象的實現。估計所使用的內存也並非易事。例如,如果字符串較短,則字符串可以嵌入到RString結構中,但如果字符串很長,則可以將其存儲在堆中(Never create Ruby strings longer than 23 characters)。

通過某些對象採取的存儲器已被列出爲不同Ruby實現:Memory footprint of objects in Ruby 1.8, EE, 1.9, and OCaml

最後,對象尺寸甚至可以與兩個對象從相同類的不同,因爲它能夠任意地添加額外的實例變量,而不用硬編碼存在什麼實例變量。例如,看instance_variable_getinstance_variable_set


如果使用MRI紅寶石1.9.2+,還有你可以嘗試(注意它是看僅對象的一部分的方法,這是顯而易見的事實是整數和字符串似乎有大小爲零):

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 

您也可以嘗試memsize_of_all(請注意,它看起來在整個解釋的內存使用情況和覆寫變量似乎並沒有刪除舊的副本立即):

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解釋器將執行垃圾回收時不能保證。雖然您可能會將其用於測試和實驗,但建議您不要在生產中使用它!

+0

那怎麼樣呢。是否可以初始化X個類,然後在之前和之後拉取ruby解釋器的內存使用情況?我遇到了一個問題,每個套接字在他們自己的線程中都會得到我的三個類的一個副本(用於數據包處理等),因此如果有10個連接是每個類的30個實例。我想知道這是否是一個基本的設計問題,我將不得不重新編碼/認爲我的數據包處理,或者如果3個類導致內存使用量很小。 – 2013-05-09 07:48:56

+0

這是產生有趣的結果,當我只是運行'puts ObjectSpace.memsize_of_all'我得到的值估計爲'1180174',但是當我運行'(0..1000).each do | i |; t.push PacketParser.new i; end'和'放入ObjectSpace。memsize_of_all'我得到'920578',這比沒有初始化我的類3000多少要少。除了垃圾處理之外,還有什麼我在這裏失蹤?是不是真的創建了3000個類,而只是簡單地引用了3個類? – 2013-05-09 08:03:27

+0

我很難回答 - 你可以檢查每一次迭代(也許你會看到在一些迭代中突然減少)。你應該知道,你不僅在上面的迭代中爲你的對象分配內存。 PacketParser構造函數和t.push方法也可以分配局部變量,這些變量會暫時增加內存使用量。 – ronalchn 2013-05-09 08:16:24

相關問題