本文将告诉大家一个黑科技方法在运行时动态获取对象本身占用空间,不包括对象引用的其他对象的空间大小的方法
通过不安全代码和反射获取对象类型的 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 里面默认将会做内存的对齐,因此对象占用空间大小将会大于等于字段占用空间大小的总数
获取某类型对象占用空间大小的方法如下
public static unsafe Int32 SizeOf<T>() { return ((MethodTableInfo*)(typeof(T).TypeHandle.Value.ToPointer()))->Size; }
本文所有代码放在 github 和 gitee 欢迎小伙伴访问
本文的这个方法获取到的对象内存具体是什么?还请看 伟民哥翻译的 《.NET内存管理宝典 - 提高代码质量、性能和可扩展性》 这本书

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。 欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。