猿问
下载APP

如何检查结构消耗的字节数?

如何检查结构消耗的字节数?

如果我创建一个相对较大的结构,我如何计算它在内存中占用的字节数?

我们可以手动完成,但如果结构足够大,那么我们该怎么做呢?是否有一些代码块或应用程序?


交互式爱情
浏览 49回答 3
3回答

largeQ

您可以使用sizeof运算符或SizeOf函数。这些选项之间存在一些差异,请参阅参考链接以获取更多信息。无论如何,使用该函数的一个好方法是使用这样的泛型方法或扩展方法:static&nbsp;class&nbsp;Test{ &nbsp;&nbsp;static&nbsp;void&nbsp;Main() &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//This&nbsp;will&nbsp;return&nbsp;the&nbsp;memory&nbsp;usage&nbsp;size&nbsp;for&nbsp;type&nbsp;Int32: &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;size&nbsp;=&nbsp;SizeOf<Int32>(); &nbsp;&nbsp;&nbsp;&nbsp;//This&nbsp;will&nbsp;return&nbsp;the&nbsp;memory&nbsp;usage&nbsp;size&nbsp;of&nbsp;the&nbsp;variable&nbsp;'size': &nbsp;&nbsp;&nbsp;&nbsp;//Both&nbsp;lines&nbsp;are&nbsp;basically&nbsp;equal,&nbsp;the&nbsp;first&nbsp;one&nbsp;makes&nbsp;use&nbsp;of&nbsp;ex.&nbsp;methods &nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;size.GetSize(); &nbsp;&nbsp;&nbsp;&nbsp;size&nbsp;=&nbsp;GetSize(size); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;static&nbsp;int&nbsp;SizeOf<T>() &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;static&nbsp;int&nbsp;GetSize(this&nbsp;object&nbsp;obj) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;System.Runtime.InteropServices.Marshal.SizeOf(obj); &nbsp;&nbsp;}}

胡说叔叔

很长一段时间,结构在计算机工程中一直是麻烦的野兽。它们的内存布局与硬件有关。为了使它们有效,它们的成员必须对齐,以便CPU可以快速读取和写入它们的值,而无需多路复用字节以适应内存总线宽度。每个编译器都有自己的成员打包策略,通常由例如C或C ++程序中的#pragma pack指令指示。这是可以的,但在互操作方案中是一个问题。其中一个代码块可能对结构布局做出不同于另一个块的假设,由另一个编译器编译。你可以在COM,.NET的祖父解决方案中看到这个互操作编程。COM具有非常的处理结构的支持比较差。它不支持它们作为本机自动化类型,但通过IRecordInfo接口有一个解决方法。这允许程序通过在类型库中显式声明结构来在运行时发现内存布局。哪个工作正常,但效率很低。.NET设计者做出了非常勇敢,正确的决定来解决这个问题。他们使结构的内存布局完全无法发现。没有记录的方法来检索成员的偏移量。而通过扩展,无法发现结构的大小。每个人最喜欢的答案,使用Marshal.SizeOf()实际上不是解决方案。在编组后,返回struct&nbsp;的大小,在调用Marshal.StructureToPtr之前,需要传递给Marshal.AllocCoTaskMem()的大小。根据与struct关联的[StructLayout]属性排列和对齐struct成员。请注意,结构不需要此属性(类似于类),运行时实现默认的属性,该属性使用成员的声明顺序。布局无法发现的一个非常好的副作用是CLR可以用它来玩弄技巧。打包结构的成员并对齐它们时,布局可能会出现不存储任何数据的漏洞。称为填充字节。鉴于布局是不可发现的,CLR实际上可以使用填充。如果它足够小以适合这样的洞,它会移动一个成员。现在,您将获得一个结构,其大小小于给定声明的结构布局时通常需要的结构。而且,值得注意的是,Marshal.SizeOf()将返回错误的结构大小值,它返回的值太大。长话短说,没有通用的方法来以编程方式获得结构大小的准确值。最好的办法就是不要问这个问题。假设结构是blittable,Marshal.SizeOf()将给你一个估计。如果由于某种原因需要准确的值,那么您可以查看生成的结构类型的局部变量的方法的机器代码,并将其与没有该局部变量的相同方法进行比较。您将看到堆栈指针调整的差异,即方法顶部的“sub esp,xxx”指令。当然,它将依赖于体系结构,您通常会在64位模式下获得更大的结构。

一只萌萌小番薯

您可以将sizeof()关键字用于不包含任何字段或属性作为引用类型的用户定义结构,也可以使用Marshal.SizeOf(Type)或Marshal.SizeOf(object)获取具有顺序或显式布局的类型或结构的非托管大小。
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答