本文将告诉大家一个黑科技方法在运行时动态获取对象本身占用空间,不包括对象引用的其他对象的空间大小的方法
此方法是在开源仓库 sidristij/dotnetex: Gets size of .Net Framework objects, can change type of object to incompatible and can alloc .Net objects at unmanaged memory area 找到的方法
通过不安全代码和反射获取对象类型的 MethodTableInfo 即可在 MethodTableInfo 里面读取 Size 属性,关于 MethodTableInfo 的定义如下
/// <summary>
/// Description of GCEnumerator.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public unsafe struct MethodTableInfo
{
#region Basic Type Info
[FieldOffset(0)]
public MethodTableFlags Flags;
[FieldOffset(4)]
public int Size;
[FieldOffset(8)]
public short AdditionalFlags;
[FieldOffset(10)]
public short MethodsCount;
[FieldOffset(12)]
public short VirtMethodsCount;
[FieldOffset(14)]
public short InterfacesCount;
[FieldOffset(16)]
public MethodTableInfo* ParentTable;
#endregion
[FieldOffset(20)]
public ObjectTypeInfo* ModuleInfo;
[FieldOffset(24)]
public ObjectTypeInfo* EEClass;
}
以上代码关键属性是 Size 属性,通过 Size 属性可以拿到运行时的对象占用空间大小。在 CLR 里面默认将会做内存的对齐,因此对象占用空间大小将会大于等于字段占用空间大小的总数
获取某类型对象占用空间大小的方法如下
/// <summary>
/// Gets type size in unmanaged memory (directly in SOH/LOH) by type
/// </summary>
public static unsafe Int32 SizeOf<T>()
{
return ((MethodTableInfo*)(typeof(T).TypeHandle.Value.ToPointer()))->Size;
}
本文所有代码放在 github 和 gitee 欢迎小伙伴访问
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙,不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。