3 回答
TA贡献1826条经验 获得超6个赞
首先,一个警告:接下来的内容严格地说是丑陋的,无证件的黑客攻击。不要依赖于这项工作 - 即使它现在适用于您,它可能会在明天停止工作,任何次要或主要的.NET更新。
您可以使用本文中有关CLR内部MSDN杂志2005年5月的信息 - 深入了解.NET框架内部以了解CLR如何创建运行时对象 - 最后我检查过,它仍然适用。这是如何完成的(它通过TypeHandle
类型检索内部“基本实例大小”字段)。
object obj = new List<int>(); // whatever you want to get the size ofRuntimeTypeHandle th = obj.GetType().TypeHandle;int size = *(*(int**)&th + 1);Console.WriteLine(size);
这适用于3.5 SP1 32位。我不确定64位上的字段大小是否相同 - 如果不是,则可能需要调整类型和/或偏移量。
这适用于所有“普通”类型,所有实例都具有相同的,定义良好的类型。那些不成对的是数组和字符串肯定,我也相信StringBuilder
。对于它们,您将所有包含的元素的大小添加到它们的基本实例大小。
TA贡献1865条经验 获得超7个赞
对于非托管类型,也就是值类型,结构:
Marshal.SizeOf(object);
对于托管对象,我得到的更接近是近似值。
long start_mem = GC.GetTotalMemory(true); aclass[] array = new aclass[1000000]; for (int n = 0; n < 1000000; n++) array[n] = new aclass(); double used_mem_median = (GC.GetTotalMemory(false) - start_mem)/1000000D;
不要使用序列化。二进制格式化程序会添加标题,因此您可以更改类并将旧的序列化文件加载到已修改的类中。
它也不会告诉你内存中的实际大小,也不会考虑内存对齐。
[编辑]通过在类的每个属性上递归使用BiteConverter.GetBytes(prop-value),您将获得以字节为单位的内容,这不计算类或引用的权重,但更接近现实。如果大小很重要,我建议使用字节数组进行数据和非托管代理类使用指针转换访问值,请注意这将是非对齐内存,因此在旧计算机上会很慢但是现代RAM上的巨大数据集将会是更快,因为最小化从RAM读取的大小将比未对齐更大的影响。
- 3 回答
- 0 关注
- 609 浏览
添加回答
举报