【问题标题】:Does creating new instances consume memory when declared in a loop?在循环中声明时创建新实例会消耗内存吗?
【发布时间】:2017-11-01 09:15:43
【问题描述】:
List<object> obj = new List<object>();
List<objectTypeof_d> list = new List<objectTypeof_d>();

foreach (Object o in obj)
{
    d = new Object();
    d = o;
    list.add(d);
}

我试图理解,当我们在循环中声明 d = new Object(); 时,每次循环都会创建新的对象实例。更好的编码或下面是正确的。

List<object> obj = new List<object>();
List<objectTypeof_d> list = new List<objectTypeof_d>();

foreach (Object o in obj)
{
    d = new Object();
    d = o;
    list.add(d);
    d = null;
} 

这只是为了理解忽略语法,或者假设对象在循环中添加到列表中。添加后我们是否可以将其设置为空。仅用于内存优化。

【问题讨论】:

  • 在 new 之后,您将通过 new 分配变量 d 获得的引用更改为 o 的引用。因此,您的新产品没用,您可以将其删除。因此你的问题是......?
  • 您正在迭代一个空列表 (obj)。你必须往里面放点东西。
  • 只是为了理解上面的loop right或者设置obj=null来处理使用后的对象。就是这样。
  • @DhruvParmar 不,设置something = null 不是处理某物的正确方法。垃圾收集器负责处理它。但是,有些东西,比如 SqlConnection 等,使用垃圾收集器无法影响的非托管资源 - 这些东西需要调用它们的 .Dispose() 方法。

标签: c# .net oop


【解决方案1】:

您似乎没有掌握引用的概念。
我建议阅读此Values vs Reference Types

在您的第一个示例中,您创建了一个调用 d = new Object(); 的对象的新实例。这个变量 d 引用了一个内存区域来存储您的对象(我假设您在这里使用 Object 只是示例)。

现在下面的行将存储在 d 中的值(参考值)更改为存储在 o 中的参考值。因此第一个引用丢失并准备好被垃圾收集。

说了,很明显你这里真正的优化,就是去掉变量d和对new object()的调用。 (还有对d = null;的调用)

无论如何,还要维护您的实际代码,设置变量d = null; 不会改变您的内存占用。真正的内存清理是在垃圾收集器运行时执行的,这个时间由系统在需要该进程运行时选择。

认为“我需要更多可用内存,让我们强制垃圾收集器运行”通常是个坏主意。

【讨论】:

  • “这样想通常是个坏主意……”我会更进一步说“假设这个总是一个坏主意”。
  • 我同意你的看法。我从未调用过 GC.Collect,但可能存在边缘情况。参见例如this answer from Jon Skeet
【解决方案2】:

new 将始终创建一个新实例,无论它是否处于循环中。因此,在您的情况下,您正在创建 Object 的多个实例并将它们丢弃,因为您正在通过行 d = o 覆盖对该实例的唯一引用。我想您可以简单地删除该行并改写:

foreach (Object o in obj)
{
    list.add(o);
}  

甚至更简单:

list.AddRange(obj);

但是,由于您从不向 obj(BTW 列表的坏名称)添加任何内容,因此循环根本不会执行。

【讨论】:

  • 我想要答案,比如我们可以设置 object = null;循环优化内存。
  • 不,这几乎都是无操作的,除非你有一个长时间运行的代码块。通常垃圾收集器会体面地丢弃这些实例。
  • 垃圾收集器什么时候会抛出实例?
  • 当它决定的时候。这是没有更多引用实例的时候。在您的情况下,这取决于您在哪里声明 d
  • @DhruvParmar 如果你需要关心什么时候,你的对象应该实现IDisposable
猜你喜欢
  • 1970-01-01
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 2011-11-29
  • 2015-01-16
  • 2011-12-15
相关资源
最近更新 更多