gpt4 book ai didi

c# - 数组或对象的指针/引用句柄会影响其大小吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:11:34 27 4
gpt4 key购买 nike

我知道,如果我有一个数组 int A[512],那么引用 A 可以指向第一个元素。在指针运算中,内存被引用为 A + index

但如果我没记错的话,指针/引用也会占用一个机器字空间。假设一个int占一个机器字,是不是意味着上面数组的512个整数占了513个字的空间?

C++ 或 C# 中的对象及其数据成员是否相同?

更新:哇,你们真快。澄清一下,我感兴趣的是 C++ 和 C# 在处理此问题的方式上不同,以及我如何调整对象大小以适合缓存行(如果可能)。

更新:我已经意识到指针和数组之间的区别。我知道数组不是指针,我上面引用的指针算法只有在数组转换为指针后才有效。但是,我认为这种区别与整个问题无关。我对数组和其他对象在 C++ 和 C# 中如何存储在内存中很感兴趣。

最佳答案

请注意,当您谈论将数据放入缓存行时,包含引用的变量和它所引用的实际数据不会位于非常接近的位置。该引用最终会在寄存器中结束,但它可能最初作为另一个对象的一部分存储在内存中的其他地方,或者作为堆栈上的局部变量。数组内容本身在被操作时仍然可以适合缓存行,而不管与“对象”相关联的任何其他开销。如果您对这在 C# 中的工作方式感到好奇,Visual Studio 有一个反汇编程序 View ,它显示为您的代码生成的实际 x86 或 x64 程序集。

数组引用在 IL(中间语言)级别具有特殊的内置支持,因此您会发现加载/使用内存的方式与在 C++ 中使用数组基本相同。在幕后,对数组进行索引是完全相同的操作。您将开始注意到差异的地方是,如果您使用“foreach”对数组进行索引,或者当数组是对象类型数组时开始不得不“拆箱”引用。

请注意,当您在方法中本地实例化对象时,C++ 和 C# 之间的内存局部性可能会有所不同。 C++ 允许您在堆栈上实例化数组,这会创建一种特殊情况,其中数组内存实际上存储在靠近“引用”和其他局部变量的位置。在 C# 中,(托管)数组的内容将始终在堆上分配。

另一方面,当提到堆分配的对象时,C# 有时可以比 C++ 具有更好的内存局部性,尤其是对于短期对象。这是由于 GC 按对象的“世代”(它们存活了多长时间)存储对象的方式及其进行的堆压缩。生命周期短的对象会在不断增长的堆上快速分配;收集时,堆也会被压缩,防止“碎片化”,这种“碎片化”会导致未压缩堆中的后续分配分散在内存中。

您可以在 C++ 中使用“对象池”技术(或通过避免频繁使用短生命周期的小对象)获得类似的内存局部性优势,但这需要一些额外的工作和设计。当然,这样做的代价是 GC 必须运行,线程劫持、提升世代、压缩和重新分配引用会在有些不可预测的时间导致可测量的开销。在实践中,开销很少成为问题,尤其是对于 Gen0 集合,它针对频繁分配的短期对象的使用模式进行了高度优化。

关于c# - 数组或对象的指针/引用句柄会影响其大小吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15229055/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com