本文将告诉大家一个黑科技方法在运行时动态获取对象本身占用空间,不包括对象引用的其他对象的空间大小的方法
通过不安全代码和反射获取对象类型的 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内存管理宝典 - 提高代码质量、性能和可扩展性》 这本书
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/dotnet-%E8%BF%90%E8%A1%8C%E6%97%B6%E8%8E%B7%E5%8F%96%E6%9F%90%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AF%B9%E8%B1%A1%E5%8D%A0%E7%94%A8%E5%86%85%E5%AD%98%E5%A4%A7%E5%B0%8F.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。
无盈利,不卖课,做纯粹的技术博客
以下是广告时间
推荐关注 Edi.Wang 的公众号
欢迎进入 Eleven 老师组建的 .NET 社区
以上广告全是友情推广,无盈利