C# C如何在临时字符串数组被垃圾回收之前销毁它?
我有一个字符串,其中包含逗号分隔的电子邮件地址。然后我将其加载到一个字符串数组中,然后填充一个更容易使用的列表。一旦填充了该列表,我希望能够销毁现在未使用的字符串数组,因为在垃圾收集器清理这些内存浪费之前,该类还有很多工作要做 如何手动销毁此字符串数组 在查看代码时,如果您有一种更干净、更有效的填充列表的方法,欢迎推荐 以下是代码:C# C如何在临时字符串数组被垃圾回收之前销毁它?,c#,C#,我有一个字符串,其中包含逗号分隔的电子邮件地址。然后我将其加载到一个字符串数组中,然后填充一个更容易使用的列表。一旦填充了该列表,我希望能够销毁现在未使用的字符串数组,因为在垃圾收集器清理这些内存浪费之前,该类还有很多工作要做 如何手动销毁此字符串数组 在查看代码时,如果您有一种更干净、更有效的填充列表的方法,欢迎推荐 以下是代码: public class EmailReportManager { private List<string> emailAd
public class EmailReportManager
{
private List<string> emailAddresses;
public EmailReportManager(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.....
}
}
然后,如果您真的想强制GC,则调用此函数,只需将其设置为null,并让GC在自己的时间内完成其工作:
GC.Collect();
还可以看到这个问题:我认为您可以使用List类的AddRange方法使代码更易于阅读
你不能破坏阵列。选项包括: 您可以使用array.clear清除数组,这样它就不再包含对任何字符串的引用。这不会回收任何内存。 您可以将该变量设置为null,以便该特定变量不会阻止对数组进行垃圾收集。这不会回收任何内存。 在确保不再有对数组的任何引用之后,可以调用GC.Collect。这可能会回收内存,虽然不能保证,但通常不是一个好主意。特别是,定期强制执行完整GC可能会严重损害性能。 值得理解的是,在您的情况下,您不需要将数组变量设置为null——它无论如何都会超出范围。即使它不打算超出范围,如果它不打算在方法的其余部分中使用,并且JIT可以告诉您,那么将它设置为null将是毫无意义的。GC可以非常可靠地判断变量何时不再相关。为了GC,将变量设置为null很少是一个好主意-如果您发现需要,这通常表明您可以将代码重构为更模块化的代码
信任GC通常是个好主意。为什么你认为GC不会抽出时间来回收你的阵列,你有真正的理由关心吗?即使在Windows XP上,你也至少有2GB的内存可供使用。您真的离使用2GB太近了,以至于需要担心提前几秒钟释放内存吗?您根本不需要做任何事情来使阵列成为垃圾收集的候选阵列,而且您不应该做任何事情,因为您尝试的每件事都只会浪费时间。垃圾收集器将在方便的时候收集阵列,并且在几乎所有情况下,垃圾收集器都有比您可能预期的更多的关于当前内存使用状态的信息 从不再使用数组的那一刻起,即当您退出从中复制的循环时,垃圾收集器就知道可以删除它。无需清除对数组的引用,因为垃圾收集器已经知道它不再被使用,所以唯一需要处理的就是浪费几个处理器周期。在数组上调用Clear来删除引用只是浪费时间,实际上会使数组在内存中保留更长的时间,因为在清除之前,垃圾收集器无法删除它 此外,数组中的所有字符串现在都在列表中,因此唯一可以进行垃圾收集的是引用数组。引用指向的所有字符串仍在使用中,因此收集数组不会释放大量内存
private void loadAddresses(string emailAddressesCommaSeperatedList) {
emailAddresses = new List<String>();
foreach (string s in emailAddressesCommaSeperatedList.Split(','))
{
emailAddresses.Add(s.Trim());
}
}
在使用函数add=Wow之前,需要先实例化列表,这看起来确实非常有用,谢谢你的建议。它不仅可读性更好,而且还减少了内存分配的数量,因为列表预先知道将有多少元素。我认为你不能真正“强制”GC运行。调用GC.Collect只会给GC一个提示。在这种情况下,将地址设置为null是完全没有意义的。更多细节请参见我的答案。谢谢Jon,非常有兴趣了解。所以我想真正的解决办法是尽量不使用临时占位符字符串数组,而是按照凯恩的建议直接使用列表上的AddRange方法。@JL:这仍然会创建一个数组-它只是不使用单独的数组变量,而且,由于AddRange知道如何更恰当地处理阵列和其他IList实现,因此它将更加高效。但是您应该知道,阵列仍然存在,仍然需要进行垃圾收集,并且仍然不需要任何特殊处理。不,只是尽可能地进行优化。您是否有充分的理由相信您需要对其进行优化?像往常一样,先编写完成任务的最清晰的代码,然后衡量性能是否有问题,如果有问题, 在尝试解决问题之前,先找出性能下降的地方。
public class EmailReportManager
{
private List<string> emailAddresses = null;
public EmailReportManager(string emailAddressesCommaSeperatedList)
{
this.emailAddresses.AddRange(emailAddressesCommaSeperatedList.Split(","))
}
}
private void loadAddresses(string emailAddressesCommaSeperatedList) {
emailAddresses = new List<String>();
foreach (string s in emailAddressesCommaSeperatedList.Split(','))
{
emailAddresses.Add(s.Trim());
}
}