C# How can I destroy a temporary string array before it gets garbage collected?
I have a string that contains comma seperated email addresses. I then load this into a string array, and from then populate a list which is easier to work with. Once the list is populated, I would like to be able to destroy the now unused string array, because the class still has a lot of work to do before the garbage collector will clean up this waste of memory.
How can I manually destroy this string array...
While reviewing the code, if you have a cleaner more efficient way of populating the list, recommendations are welcome.
Here is code:
public class EmailReportManager
{
private List<string> emailAddresses;
public EmailRepor开发者_运维百科tManager(string emailAddressesCommaSeperatedList)
{
loadAddresses(emailAddressesCommaSeperatedList);
}
private void loadAddresses(string emailAddressesCommaSeperatedList)
{
string[] addresses = emailAddressesCommaSeperatedList.Split(',');
for (int addressCount = 0; addressCount < addresses.Length; addressCount++)
{
this.emailAddresses.Add(addresses[addressCount]);
}
//Want to destroy addresses here.....
}
}
You can't "destroy" the array. Options are:
- You can clear the array using
Array.Clear
, so that it won't hold references to any strings any more. This won't reclaim any memory. - You can set the variable to null, so that that particular variable doesn't prevent the array from being garbage collected. This won't reclaim any memory.
- You could call
GC.Collect
after making sure you don't have any references to the array any more. This will probably reclaim the memory (it's not guaranteed) but it's generally not a good idea. In particular, forcing a full GC regularly can significantly harm performance.
It's worth understanding that in your case you don't need to set the array variable to null - it's about to go out of scope anyway. Even if it wasn't about to go out of scope, if it wasn't going to be used in the rest of the method (and the JIT could tell that) then setting it to null would be pointless. The GC can pretty reliably tell when a variable is no longer relevant. It's rarely a good idea to set a variable to null for the sake of GC - if you find you want to, that's usually an indication that you could refactor your code to be more modular anyway.
It's usually a good idea to just trust the GC. Why do you think the GC isn't going to get round to reclaiming your array, and do you have a really good reason to care?
addresses = null;
Then if you really want to force GC, call this (otherwise, just set it to null and let the GC do its job on its own time):
GC.Collect();
Also see this question: Force garbage collection of arrays, C#
I think you can make the code easier to read by using the AddRange method of the List<> class.
public class EmailReportManager
{
private List<string> emailAddresses = null;
public EmailReportManager(string emailAddressesCommaSeperatedList)
{
this.emailAddresses.AddRange(emailAddressesCommaSeperatedList.Split(","))
}
}
You don't need to do anything at all to make the array a candidate for garbage collection, and you shouldn't do anything, as everything that you try will only be a waste of time. The garbage collector will collect the array at a convenient time, and in almost every case the garbage collector has a lot more information about the current state of memory usage than what you can possibly anticipate.
From the moment that the array is not used any more (i.e. when you exit the loop where you copy from it), the garbage collector knows that it can be removed. There is no need to clear the reference to the array as the garbage collector already knows that it's no longer used, so the only thing that accompishes is a waste of a few processor cycles. Calling Clear on the Array to remove the references from it is just a waste of time, and will actually keep the array in memory longer as the garbage collector can't remove it until you have cleared it.
Besides, all the strings from the array is now in the list, so the only thing that can be garbage collected is the array of references. All the strings that the references point to are still in use, so collecting the array doesn't free a lot of memory.
private void loadAddresses(string emailAddressesCommaSeperatedList) {
emailAddresses = new List<String>();
foreach (string s in emailAddressesCommaSeperatedList.Split(','))
{
emailAddresses.Add(s.Trim());
}
}
the list needs to be instantiated first before using the function add =)
Even on Windows XP, you have at last 2GB of memory at your disposal. Are you really that close to using 2GB that you need to worry about releasing the memory a few seconds earlier?
精彩评论