【问题标题】:What's the difference in memory between creating an object inside and outside of a loop在循环内部和外部创建对象之间的内存有什么区别
【发布时间】:2013-12-06 22:39:23
【问题描述】:

我想弥补我知识上的一些空白。从此开始。

示例(c#):

List<Person> names = new List<Person>();

Person friend = null;
for(int i = 0; i < 5; i++)
{
    friend = new Person();
    Person guy = new Person();

    guy.name = "Bob" + i;
    friend.name = "Bill" + i;

    names.Add(guy);
    names.Add(friend);
}

为了节省空间,我在同一个循环中使用了两个 Person 对象。

我的理解是,每次实例化朋友时,我都会重用内存中的相同位置,覆盖现有的 Person 对象(如果存在)。

而每个新的“人”对象都被分配了一个新的内存位置。

如果这是正确的,如果有错误请纠正我,这意味着使用“friend”而不是“guy”更节省内存。

会不会出现“男人”会更好的情况?会不会依赖于构造函数的实现?

【问题讨论】:

    标签: c# memory-efficient


    【解决方案1】:

    据我了解,每次实例化朋友时,我都会重用内存中的相同位置,覆盖现有的 Person 对象(如果存在)。

    不,事实并非如此。您正在覆盖 variable 中的先前值 - 但这不是对象。这只是对象的引用。列表中有另一个对该对象的引用。对象本身根本不会被覆盖。您创建的每个对象都独立于其他对象。

    就在循环内或循环外声明变量的区别而言,并没有太大区别。有一些区别:

    • 如果它是在循环外声明的,您可以在为它分配新值之前在循环内使用该变量,这样您就可以看到之前的值
    • 如果在循环外声明,也可以使用循环后的变量,读取最后赋值的值
    • 如果它是在循环外声明的,并且您在循环内部使用匿名函数,那么每个匿名函数都会捕获相同的变量。如果它在循环内,每个匿名函数都会捕获一个 不同 变量。如果此刻所有这些对你来说听起来像是 gobbledygook,你可以忽略它
    • 如果它是在循环内声明的,那么您可以在单独的块中声明一个具有相同名称的单独变量;如果它是在循环之外声明的,则不能这样做。

    我通常建议在您第一次需要它的时候以尽可能小的范围声明变量 - 我发现这样可以得到更清晰的代码。

    【讨论】:

    • 谢谢。真的很棒的解释。不,我明白,这只是我从未完全理解的事情之一。再次感谢!
    【解决方案2】:

    在循环内部和外部创建对象的内存有什么区别?

    不,在这两种情况下,您都会在循环内创建新的 Person 对象。您只是在循环内部创建一个 variable 并在外部创建一个 variable。这两者之间的唯一区别是循环完成后,friend 仍然包含对您在循环内分配给它的最后一个实例的引用。

    我的理解是,每次实例化朋友时,我都会重用内存中的相同位置,覆盖现有的 Person 对象(如果存在)。

    不,事实并非如此。每次实例化 Person 时,完全取决于运行时存储新实例的位置。您不会覆盖以前的实例,您所做的只是重用您用来引用每个新实例的 变量

    删除对实例的所有引用后,garbage collector 可能会释放与该旧实例关联的内存,以便以后重用该内存。但是在这里,您将每个实例添加到列表中,因此在 names 列表被清除或销毁(以及其他可能存在的任何其他实例)之前,它们不会被收集。

    【讨论】:

    • 非常有帮助!绝对有助于我的理解。干杯
    【解决方案3】:

    据我了解,每次实例化朋友时,我都会重用内存中的相同位置,覆盖现有的 Person 对象(如果存在)。

    这种理解是错误的。您断开了从朋友变量到内存中对象的连接,但内存中的前一个对象仍然存在。如果没有对该对象的其他引用,它将有资格进行收集,但不能保证何时进行收集。在这种情况下,您仍然拥有对旧对象的现有引用(通过 names 集合),因此您的代码中唯一的区别是创建并分配给 friend 变量的最后一个对象在循环之后仍然可以访问。

    【讨论】:

      【解决方案4】:

      当您创建新朋友时,您并没有重复使用内存位置。您创建新对象并将其地址分配给朋友变量。这样你就“忘记”了以前的朋友。

      所以它不是更有效的内存。如果你在 for 循环之后不使用friend,那么在for 中定义friend 变量也会更简洁,就像你对guy 所做的那样。

      【讨论】:

      • 我明白了。感谢您的意见。
      猜你喜欢
      • 1970-01-01
      • 2016-04-29
      • 2020-06-17
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多