Skip to content

dotnet 运行时获取某类型的对象占用内存大小

Updated: at 08:22,Created: at 13:15

本文将告诉大家一个黑科技方法在运行时动态获取对象本身占用空间,不包括对象引用的其他对象的空间大小的方法

此方法是在开源仓库 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 里面默认将会做内存的对齐,因此对象占用空间大小将会大于等于字段占用空间大小的总数

获取某类型对象占用空间大小的方法如下

public static unsafe Int32 SizeOf<T>()
{
return ((MethodTableInfo*)(typeof(T).TypeHandle.Value.ToPointer()))->Size;
}

本文所有代码放在 githubgitee 欢迎小伙伴访问

本文的这个方法获取到的对象内存具体是什么?还请看 伟民哥翻译的 《.NET内存管理宝典 - 提高代码质量、性能和可扩展性》 这本书


知识共享许可协议

原文链接: http://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

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