有没有办法以编程方式准确确定 C# 中对象使用的内存量?我不关心这个过程有多慢,所以左右运行 GC 是可以接受的(当然我更喜欢更高效的东西)。
序列化对象并查看结果长度似乎不太准确(在对此方法的简单测试中,我看到整数返回值 54)。
Using GC.GetTotalMemory(true)
似乎会产生不一致的值,更不用说它们看起来太大了。
Using Marshal.SizeOf(object)
产生准确的结果,但似乎只适用于基元。
如果没有任何可用的方法,另一种方法是根据所使用的结构和所涉及的基元来计算大小。这也是可以接受的(尽管令人不安),但我需要知道计算对象开销的正确方法等。任何能向我展示一种方法的文献都会很棒。
类似的SO问题(似乎都没有准确计算对象大小的具体方法):
C#/.NET 对象使用多少内存? https://stackoverflow.com/questions/426396/how-much-memory-does-a-c-net-object-use
如何在 C# 中获取可用或已使用的内存 https://stackoverflow.com/questions/750574/how-to-get-memory-available-or-used-in-c-sharp
如何获取内存中对象的大小? https://stackoverflow.com/questions/605621/how-to-get-object-size-in-memory
sizeof() 相当于引用类型? https://stackoverflow.com/questions/26570/sizeof-equivalent-for-reference-types
分析内存的工具(非编程方法):
http://www.microsoft.com/en-us/download/details.aspx?id=16273 http://www.microsoft.com/en-us/download/details.aspx?id=16273
找出 C# 中的对象使用了多少内存? https://stackoverflow.com/questions/60820/find-out-how-much-memory-is-being-used-by-an-object-in-c
另一个想法是有一个辅助类来通过反映对象并提取其所有数据成员并通过 sizeof() 收集所有字段大小来完成此操作,这会有点复杂,但它是可以实现的
这个类将计算一个对象的实际大小,但我只测试了几次,并且测试了一些对象,但我想我会工作。
public class SizeHelper
{
private static int GetTypeSizeArray(string typeName, object objValue)
{
switch (typeName)
{
case "System.Double[]":
return sizeof(System.Double) * ((System.Double[]) objValue).Length ;
case "System.Single[]":
return sizeof(System.Single) * ((System.Single[])objValue).Length;
case "System.Char[]":
return sizeof(System.Char) * ((System.Char[])objValue).Length;
case "System.Int16[]":
return sizeof(System.Int16) * ((System.Int16[])objValue).Length;
case "System.Int32[]":
return sizeof(System.Int32) * ((System.Int32[])objValue).Length;
case "System.Int64[]":
return sizeof(System.Int64) * ((System.Int64[])objValue).Length;
case "System.UInt16[]":
return sizeof(System.UInt16) * ((System.UInt16[])objValue).Length;
case "System.UInt32[]":
return sizeof(System.UInt32) * ((System.UInt32[])objValue).Length;
case "System.UInt64[]":
return sizeof(System.UInt64) * ((System.UInt64[])objValue).Length;
case "System.Decimal[]":
return sizeof(System.Decimal) * ((System.Decimal[])objValue).Length;
case "System.Byte[]":
return sizeof(System.Byte) * ((System.Byte[])objValue).Length;
case "System.SByte[]":
return sizeof(System.SByte) * ((System.SByte[])objValue).Length;
case "System.Boolean":
return sizeof (System.Boolean)*((System.Boolean[]) objValue).Length;
default:
return 0;
}
}
public static int GetSize(object obj)
{
Type t = obj.GetType();
FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
int size = 0;
foreach (FieldInfo fieldInfo in fields)
{
if (fieldInfo.FieldType.BaseType.FullName.Equals("System.ValueType"))
{
size += GetTypeSize(fieldInfo.FieldType.FullName);
}
else if (fieldInfo.FieldType.BaseType.FullName.Equals("System.Array"))
{
var subObj = fieldInfo.GetValue(obj);
if (subObj != null)
size += GetTypeSizeArray(fieldInfo.FieldType.FullName, subObj);
}
else if(fieldInfo.FieldType.FullName.Equals("System.String"))
{
var subObj = fieldInfo.GetValue(obj);
if (subObj != null)
{
size += subObj.ToString().Length*sizeof (System.Char);
}
}
else
{
var subObj = fieldInfo.GetValue(obj);
if (subObj != null)
size += GetSize(subObj);
}
}
return size;
}
private static int GetTypeSize(string typeName)
{
switch (typeName)
{
case "System.Double":
return sizeof(System.Double);
case "System.Single":
return sizeof(System.Single);
case "System.Char":
return sizeof(System.Char);
case "System.Int16":
return sizeof(System.Int16);
case "System.Int32":
return sizeof(System.Int32);
case "System.Int64":
return sizeof(System.Int64);
case "System.UInt16":
return sizeof(System.UInt16);
case "System.UInt32":
return sizeof(System.UInt32);
case "System.UInt64":
return sizeof(System.UInt64);
case "System.Decimal":
return sizeof(System.Decimal);
case "System.Byte":
return sizeof(System.Byte);
case "System.SByte":
return sizeof(System.SByte);
case "System.Boolean":
return sizeof (System.Boolean);
default:
return 0;
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)