c# - 如何在堆中分配值类型数组?
问题描述
我阅读了一些类似问题的答案,但我的问题略有不同,因为我不理解书中关于此问题的陈述。
因为结构是值类型,每个实例不需要在堆上实例化对象;当创建一个类型的许多实例时,这会带来有用的节省。例如,创建一个值类型的数组只需要一次堆分配。
我的意思是数组如何只需要一个堆分配?...或者单个堆分配是什么意思
解决方案
首先,让我们澄清一下“堆”与“堆栈”的含义。
今天的大多数编程环境都是基于堆栈的。运行程序时,每次调用方法时,都会将新条目推送到为程序提供的特殊堆栈中。这个堆栈条目(或帧)告诉系统在哪里寻找方法的可执行代码,传递了哪些参数,以及方法退出后调用代码中返回的确切位置。当一个方法完成时,它的条目会从堆栈中移除(弹出),因此程序可以返回到前一个方法。当堆栈为空时,程序结束。
堆栈上的每一帧也有一定的空间用于方法的局部变量,而堆栈本身的大小是有限的。这就是“堆栈溢出”的来源。获取太多的方法调用太深,堆栈将耗尽空间。
另一方面,堆是不会自动授予程序的内存。这是程序必须在其核心分配之外请求的内存。堆内存必须更仔细地管理,但(通常)还有更多可用空间。因为它必须由操作系统根据请求授予,所以来自堆的初始分配也比来自堆栈的分配慢一点。
作为一个广泛的概括,我们说引用类型在堆上分配,而值类型在堆栈上分配(尽管有很多例外)。
现在我们了解了这么多,我们可以开始看数组了。
核心数组类型本身是一个引用类型。我的意思是,对于任何给定的 type T
,T
可能(或可能不是)值类型,但T[]
始终是引用类型。在“堆栈与堆”上下文中,这意味着创建一个新数组是一个堆分配,即使T
是一个值类型。数组也有固定的大小。该单一堆分配将为数组中的所有元素创建足够的空间。
值类型的另一个特性是它们具有基于成员的固定大小。所以对于一个数组,我们有固定数量的元素,每个元素都有一个已知的固定大小。这足以获取数组对象的所有空间,并且它是单个堆分配中的元素。每个项目的值都保存在数组的核心内存中。
对于保存引用类型的数组,数组的堆分配只为引用创建空间。要填充数组,您必须为每个元素进行额外分配。
这可能会因具有一个或多个引用类型成员的值类型而稍微复杂化。在这种情况下,值类型的空间是正常分配的,但引用成员的值部分只是一个引用。它仍然需要单独的分配来为这些引用成员创建对象。
推荐阅读
- .net - 在 ASP .NET 中重定向到错误页面而不是登录页面以获得错误的 AuthorizationManager 响应
- r - 无法在 macOS 上使用 devtools 在 R 中安装 lightgbm
- php - 在控制器中使用 Symfony NamespacedAttributeBags
- angular - 打字稿错误:TS2314:通用类型'ElementRef
' 需要 2 个类型参数 - python - Amazon EC2 virtualenv:pip 说它安装了 numpy 但 python 找不到它
- java-8 - 转换为 lamda 表达式
- artifactory - Artifactory 为 rpm 存储库提供 404
- kotlin - readLine 和 try.kotlinlang.org
- jqgrid - jqgrid 根据时区转换日期。如何限制它
- html - 如何在 Qualtrics 调查中包含可展开/可折叠的文本