【问题标题】:what happens to memory when reassign array in C#?在 C# 中重新分配数组时内存会发生什么?
【发布时间】:2018-01-03 01:43:38
【问题描述】:

在下面的代码中,myArray 最初指向的内存在第 2 行重新分配后会发生什么情况?是内存丢失了,还是 C# 垃圾收集器处理了它?

static void Main(string[] args)
{
   double[] myArray = new Double[10];
   myArray = new Double[3];
}

就我一直在阅读的内容而言,没有办法显式释放内存,所以我希望 C# 能自动做到这一点。

【问题讨论】:

  • 垃圾收集器会处理它
  • 数据仍会在内存中保留一段时间。因为您不再有任何指向该数据的指针,GC 将在必要时收集该空间。

标签: c# arrays memory


【解决方案1】:

当然,C# 会在分配之前自动释放与myArray 关联的内存。这不会立即发生,但一旦垃圾收集器意识到没有对该 Double[10] 数组对象* 的剩余引用,分配给该对象的内存就会被回收。

如果你稍微改变你的程序来创建对同一个数组的第二个引用,像这样

double[] myArray = new Double[10];
double[] myArray2 = myArray; // Second reference
myArray = new Double[3];

垃圾收集器不会释放该对象,只要您的程序仍然可以访问对它的引用。

* 有时您的程序在垃圾收集器完成其分析之前完成执行。不过,内存仍然会被释放。

【讨论】:

  • 一旦垃圾收集器意识到没有剩余的引用 .- 取决于应用程序的大小/在应用程序关闭后可以使用它
  • @Fabio 这很公平。我添加了一个脚注来提及这一点。谢谢!
【解决方案2】:

当您的变量超出范围并且不再需要内存时,它就有资格进行垃圾回收。

MS 解释了一切,如下所示:https://msdn.microsoft.com/en-us/library/aa691138(v=vs.71).aspx

C# 采用自动内存管理,开发人员无需手动分配和释放对象占用的内存。

自动内存管理策略由垃圾实现 集电极。对象的内存管理生命周期为 如下:

  1. 创建对象时,会为其分配内存,运行构造函数,并认为对象是活动的。
  2. 如果对象或其任何部分不能通过任何可能的继续执行访问,除了运行 析构函数,对象被认为不再使用,它​​变成 符合销毁条件。 C# 编译器和垃圾收集器 可以选择分析代码以确定对对象的哪些引用 将来可能会用到。例如,如果一个局部变量是 在范围内是对对象的唯一现有引用,但本地 变量从未在任何可能的延续中被提及 从过程中的当前执行点执行, 垃圾收集器可以(但不是必须)将对象视为没有 使用时间更长。
  3. 一旦对象符合销毁条件,在稍后某个未指定的时间,该对象的析构函数(第 10.12 节)(如果有) 对象运行。除非被显式调用覆盖,否则析构函数 该对象仅运行一次。
  4. 一旦对象的析构函数运行,如果该对象或其任何部分不能被任何可能的延续访问 执行,包括析构函数的运行,对象是 被认为不可访问,并且该对象有资格 收藏。
  5. 最后,在对象符合收集条件后的某个时间,垃圾收集器会释放与 那个对象。

如果你想了解更多细节,可以看这里:https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/index

或者我相信您也可以找到一些关于该主题的博客。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 2014-04-15
    • 2014-12-20
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    相关资源
    最近更新 更多