.net 基础库中应该是没有直接提供计算某个对象所占内存的方法。简单查了下,找到几种方式:
1、运行态用工具进行内存分析
比如,微软这篇教程中有介绍。《使用 .NET 对象分配工具分析内存使用情况》https://learn.microsoft.com/zh-cn/visualstudio/profiling/dotnet-alloc-tool
2、把对象序列化后看其占用的字节数
比如:二进制序列化、Json序列化等。以下是二进制序列化的示例代码(值得提一下的是,出于安全考虑MS已经在.NET 9.0废弃了BinaryFormatter
)
public static long MeasureObjectSize(object obj)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
return stream.Length;
}
}
3、使用 Marshal.SizeOf 方法测量
但对复杂对象是不好用的。因为该方法只方法适用于测量简单的值类型和结构体类型的大小。对于引用类型的对象,它只会返回指针的大小。需要递归遍历对象的属性,并累加大小。
示意代码如下(AI生成),完全实现其实会更复杂一些。
public static long GetSize(object obj)
{
if (obj == null)
return 0;
Type type = obj.GetType();
long size = 0;
// ValueTypes自动继承自System.ValueType
if (type.IsValueType)
{
size += Marshal.SizeOf(obj);
}
// 引用类型和数组
else
{
// 添加对象的实例字段大小
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var field in fields)
{
if (field.FieldType.IsValueType || field.FieldType.IsArray)
{
size += GetSize(field.GetValue(obj));
}
else
{
// 引用类型字段可能是null,添加一个IntPtr大小
size += IntPtr.Size;
}
}
}
return size;
}
第2、3种方法可能更多是定量估算,视需要使用吧。