3 回答

TA貢獻1828條經(jīng)驗 獲得超4個贊
基本上你不能。它將取決于填充,這可能基于您正在使用的CLR版本和處理器等。假設它沒有引用其他對象,則更容易計算出對象的總大小:創(chuàng)建一個大數(shù)組,使用GC.GetTotalMemory作為基點,使用對類型的新實例的引用填充數(shù)組,然后再次調(diào)用GetTotalMemory。取一個值遠離另一個值,除以實例數(shù)。您可能應該事先創(chuàng)建一個實例,以確保沒有新的JITted代碼對該數(shù)字有貢獻。是的,它聽起來像黑客一樣 - 但我之前已經(jīng)用它效果很好。
就在昨天,我認為為此編寫一個小助手類是個好主意。如果您有興趣,請告訴我。
編輯:還有其他兩個建議,我想解決它們。
首先,sizeof運算符:這只顯示了抽象中類型占用了多少空間,沒有應用填充。(它包括結(jié)構(gòu)中的填充,但不是在另一種類型中應用于該類型的變量的填充。)
接下來,Marshal.SizeOf:這只顯示編組后的非托管大小,而不是內(nèi)存中的實際大小。正如文檔明確指出:
返回的大小實際上是非托管類型的大小。對象的非托管和托管大小可以不同。對于字符類型,大小受應用于該類的CharSet值的影響。
再次,填充可以有所作為。
只是為了澄清我對填充相關的含義,請考慮以下兩個類:
class?FourBytes?{?byte?a,?b,?c,?d;?}class?FiveBytes?{?byte?a,?b,?c,?d,?e;?}
在我的x86盒子上,一個FourBytes實例需要12個字節(jié)(包括開銷)。FiveBytes的實例需要16個字節(jié)。唯一的區(qū)別是“e”變量 - 那么需要4個字節(jié)嗎?好吧,有點......而不是。很明顯,您可以從FiveBytes中刪除任何單個變量以將大小縮減到12個字節(jié),但這并不意味著每個變量占用4個字節(jié)(考慮刪除所有變量?。?。單個變量的成本并不是一個在這里很有意義的概念。

TA貢獻1875條經(jīng)驗 獲得超5個贊
using?System;using?System.Runtime.InteropServices;public?class?MyClass{ ????public?static?void?Main() ????{ ????????Int32?a?=?10; ????????Console.WriteLine(Marshal.SizeOf(a)); ????????Console.ReadLine(); ????}}
請注意,正如jkersch所說,可以使用sizeof,但遺憾的是只能使用值類型。如果你需要一個班級的大小,Marshal.SizeOf就是你要走的路。
Jon Skeet已經(jīng)闡明了為什么sizeof和Marshal.SizeOf都不是完美的。我想問題需要決定是否可以接受他的問題。

TA貢獻1829條經(jīng)驗 獲得超4個贊
從他在答案中的Jon Skeets食譜中我試圖制作他所指的幫助班。歡迎提出改進建議。
public class MeasureSize<T>{ private readonly Func<T> _generator; private const int NumberOfInstances = 10000; private readonly T[] _memArray; public MeasureSize(Func<T> generator) { _generator = generator; _memArray = new T[NumberOfInstances]; } public long GetByteSize() { //Make one to make sure it is jitted _generator(); long oldSize = GC.GetTotalMemory(false); for(int i=0; i < NumberOfInstances; i++) { _memArray[i] = _generator(); } long newSize = GC.GetTotalMemory(false); return (newSize - oldSize) / NumberOfInstances; }}
用法:
應該使用生成T的新實例的Func創(chuàng)建。確保每次都不返回相同的實例。這沒關系:
public long SizeOfSomeObject() { var measure = new MeasureSize<SomeObject>(() => new SomeObject()); return measure.GetByteSize(); }
- 3 回答
- 0 關注
- 732 瀏覽
添加回答
舉報