What's the difference in memory between creating an object inside and outside of a loop

683 views Asked by At

I want to clear up a few gaps in my knowledge. Starting with this.

Example (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);
}

Here I have two Person objects used in the same loop just to save space.

It is my understanding that each time I instantiate friend, I reuse the same location in memory, overwriting the existing Person object, if present.

Whereas each new "guy" object is assigned a new location of memory.

Provided this is correct, and please correct me if this is wrong, this means that using "friend" over "guy" is more memory efficient.

Would there ever be a case where "guy" would be better? Could it depend on the implementation of the constructor?

4

There are 4 answers

1
Jon Skeet On BEST ANSWER

It is my understanding that each time I instantiate friend, I reuse the same location in memory, overwriting the existing Person object, if present.

No, that's not the case. You're overwriting the previous value in the variable - but that's not the object. That's just a reference to the object. There's another reference to the object within the list. The object itself won't be overwritten at all. Each object you create is independent of the others.

In terms of the difference between declaring the variable inside the loop or outside the loop, it doesn't make much difference. There are a few differences:

  • If it's declared outside the loop, you can use the variable within the loop before assigning a new value to it, so you get to see the previous value
  • If it's declared outside the loop, you can use the variable after the loop as well, to read the last-assigned value
  • If it's declared outside the loop, and you use an anonymous function inside the loop, then every anonymous function will capture the same variable. If it's inside the loop, each anonymous function will capture a different variable. If all of this sounds like gobbledygook to you at the moment, you can probably ignore it
  • If it's declared inside the loop, then in a separate block you can declare a separate variable with the same name; you can't do that if it's declared outside the loop.

I'd generally recommend declaring variables with the minimum scope possible, at the point where you first need it - I find that ends up with clearer code.

0
Piotr Perak On

When you create new friend you are not reusing memory location. You create new object and assign it's address to friend variable. Thus you 'forget' about previous friend.

So it is not more memory efficient. And if you don't use friend after for loop it is also cleaner to define friend variable inside for just like you did with guy.

0
Joel Coehoorn On

It is my understanding that each time I instantiate friend, I reuse the same location in memory, overwriting the existing Person object, if present.

That understanding is wrong. You break the connection from the friend variable to the object in memory, but that former object in memory is still alive. If there are no other references to that object, it will be eligible for collection, but there is no guarantee when the collection will take place. In this case, you still have existing references to the old object (via the names collection), and so the only difference in your code is that the last object created and assigned to the friend variable will still be accessible following the loop.

1
p.s.w.g On

What's the difference in memory between creating an object inside and outside of a loop?

No, you're create new Person objects inside the loop in both cases. You're just creating one variable inside the loop and one variable outside. The only difference between these two is that after the loop completes, friend still contains a reference to the last instance it you assigned it inside the loop.

It is my understanding that each time I instantiate friend, I reuse the same location in memory, overwriting the existing Person object, if present.

No, this is not the case. Each time you instantiate a Person it's entirely up to the run-time where to store that new instance. You're not overwriting previous instances, all you're doing is reusing the variable that you use to reference each new instance.

Once all references to an instance are removed, the garbage collector may free the memory associated with that old instance, allowing that memory to be reused later. But here, you're adding each instance to the list, so they won't be collected until the names list is cleared or destroyed (and any other instances that might exist elsewhere).