是否在堆栈上分配了值类型的本地数组并立即收集垃圾? [复制]

Posted

技术标签:

【中文标题】是否在堆栈上分配了值类型的本地数组并立即收集垃圾? [复制]【英文标题】:Are local arrays of value types allocated on stack and garbage collected immediately? [duplicate] 【发布时间】:2021-09-29 17:32:15 【问题描述】:
public static Vector2[] To1DArray(this Vector2[,] grid)

    Vector2[] array = new Vector2[grid.Length];
    for (int i = 0; i < grid.GetLength(0); i++)
    
        for (int j = 0; j < grid.GetLength(1); j++)
        
            array[grid.GetLength(1) * i + j] = grid[i,j];
        
    
    return array;

我说的是我在函数的第一行创建的 Vector2 结构数组。

【问题讨论】:

在任何情况下,数组本身都位于堆上:***.com/questions/1113819/… 垃圾收集器是否足够聪明,可以在引用超出范围时可靠地删除它,这是一个很好的问题。跨度> The Stack Is An Implementation Detail,你不应该在意。 CLR 的当前实现总是将数组(和任何引用类型)存储在堆上,而不是堆栈上。您可以使用Buffer.BlockCopy(grid, 0, array, 0, array.Length); 缩短复制代码 【参考方案1】:

数组在堆上。

但总的来说,您不必为此担心太多。

如果你真的这样做,你应该看看“数组池”。特别是如果您的网格始终具有相同的大小。

顺便说一句,这两个数组都线性存储在内存中。

你可以简单地使用Buffer.BlockCopy

var array = new Vector2[grid.Length];
Buffer.BlockCopy(grid, 0, array, 0, grid.Length * 2 * sizeof(float));
return array;

在它们之间进行转换。

【讨论】:

【参考方案2】:

您正在返回该数组。这意味着正在返回引用,因此该数组肯定不会被垃圾收集。除非您使用“不安全模式”,否则 C# 将永远不会释放您引用的内存等(与 C++ 不同,如果您使用错误)。

在我上面的评论中,我认为您的问题与数组的性能有关,这些数组故意应该只存在于一个函数中。 但是,您的函数可以安全使用。

【讨论】:

哦,我正在创建我的网格数组的实例,并且只是返回对该实例的引用。这很有意义。谢谢!

以上是关于是否在堆栈上分配了值类型的本地数组并立即收集垃圾? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Go 中结构的堆栈与堆分配,以及它们与垃圾收集的关系

JVM垃圾收集器与内存分配策略

垃圾回收机制

-垃圾收集器内存分配策略

JVM初探- 内存分配GC原理与垃圾收集器

垃圾收集器与内存分配策略之内存分配与回收策略