开发者

List <Class> New Class takes up memory? Do I need C=null; in the code?

List New Class takes up memory?

Do I need C=null; in the code below?

//class Category
public List<Category> SelectAll()
{
  List<Category> LV = new List<Category>();  
  string command = "SELECT * from categories";
  SqlCommand sc = new SqlCommand(command, new SqlConnection(GlobalFunction.Function.GetConnectionString()));
  sc.Connection.Open();
  SqlDataReader dr = sc.ExecuteReader();

  using(dr)
  {
    while (dr.Read())
  开发者_如何学编程  {

      // My Question is does this cause a memory problem...
      Category C = new Category(); 

      C.CategoryID = Convert.ToInt32(dr["CategoryID"]);
      C.Name = dr["Name"].ToString();
      C.DisplayOrder=Convert.ToInt32(dr["DisplayOrder"]);

      LV.Add(C);

      // I was told to add this because if not it would cause a memory leak.
      C=Null;                                            

    }
  }
  sc.Connection.Close();
  return LV;
}

GridView1.DataSource = List<Category>; 
GridView1.AllowPaging = true;
GridView1.PageSize = 5;
GridView1.DataBind();


No, you do not need to explicitly set C to null.

The garbage collector determines if an object can be freed by seeing if there are any outstanding references to the object. As soon as the function SelectAll returns, the only reference to the object should be in LV, from LV.Add(C). The out of scope stack variable will not cause an additional reference, and does not need to be set to null.


C will go out of scope when the function returns and will be eligible for garbage collection so, no, you should not set C to null before exiting.

Now if C had some system resource as a member variable, e.g. a file, thread or some other limited resource that you wanted to get released as soon as possible then it should implement IDisposable, in which case you could do something like

using (Category c = new Category())
{
    // Do stuff here 
}

and that would force Dispose to get called at the end of the using block.


No, there is no need to set the reference to null, that is just unneccesary code that uses up CPU time and clutters up the code.

You have another problem in your code, though. You are only creating one instance of the class, which you reuse for each item. As you put the values into the same object they will overwrite the previous values, and you end up with a list full of references to the one single object.

Also, you are creating a new instance of the list for each iteration, so you throw away the previous list and end up with a list only containing the last item.

You need to create the list outside the loop, and create a new instance of the object inside the loop:

...
SqlDataReader dr = sc.ExecuteReader();

List<Category> LV = new List<Category>();          

using(dr) {
  while (dr.Read()) {

    Category C = new Category();

    C.CategoryID = Convert.ToInt32(dr["CategoryID"]);
    C.Name = dr["Name"].ToString();
    C.DisplayOrder=Convert.ToInt32(dr["DisplayOrder"]);

    LV.Add(C);

  }
}
sc.Connection.Close();
return LV;


No, you don't need to explicitly set C to null.

But I don't think that code does what you think it does. You create C as a new Category instance, and then you loop through the records returned from the database, set properties on C, and then add it to a List<Category>.

The problem with that is that you only create one Category object, C, and fill the LV list with references to that same object. Because you mutate the object C each time through the loop, by the end of the loop you will have n references in the list, where n is the number of rows returned in the SqlDataReader, but all n references will point to the same object, which will have its properties set according to the last record processed.

So a simpler answer would be: just move the line C = new Category(); to inside the while (dr.Read()) loop.

Also, as a side note, you might want to look into LINQ-to-SQL, which would make it much easier to do the kinds of things you're trying to do here.


In short, no.

The reason someone would think you need to do this, is that in lower level languages, like (the language) C, you would have to deallocate the memory when you were done with it. You are working in a higher level language with Garbage Collection. GC keeps track of the number of references to a particular piece of memory, and when there are none remaining, deallocates it automatically.

I believe (the Category object) C will end up persisting beyond this function, due to LV.Add(C), but later, when all the references ARE gone, it will be taken care of.

As mdenomy points out, there are some cases you do need to take action, but those are the exception not the rule. See his post for details on those exceptions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜