如何释放虚拟内存?

时间:2010-06-02 20:07:21

标签: c# memory virtual garbage-collection

我有一个从网上下载网页的抓取工具(使用C#)。 该应用程序需要更多虚拟内存, 即使我处理每个对象,甚至使用GC.Collect() .

这个,有10个线程,每个线程都有一个下载页面的套接字。 在每个帖子中,我有一个byte[] buffer来存储页面的内容,并且有 我存储在其中的string str_content,字符串中的页面内容。 我有一个Sytem.Timer,如果每个线程都已经停止,则每3秒钟一次, 分配新线程并启动它。

我使用dispose方法甚至在我的应用程序中使用GC.Collect(),但在3小时内我的应用程序需要 虚拟内存500 MB(Process Explorer中专用字节500 MB)。然后我的系统 将挂起,我应该重新启动我的电脑。

  1. 如果我将byte[]string指定为null,那会有点粗鲁吗?

  2. 我有什么方法可以用来释放虚拟内存吗?

  3. 谢谢。

3 个答案:

答案 0 :(得分:6)

首先,你不应该打电话给gc.collect(),因为这是一个代价高昂的电话,而且不应该是必要的。

如果您看到增长并且您仍然在调用gc.collect(),那么您的资源仍有参考资料,因此无法收集这些资源。

我会开始查看您的代码并确保所有对象都在适当的范围内声明,您正在使用Using Statement语法来确保正确清理实现IDisposable的项目并对您的内容进行全面审核代码。

下一步是采用像ANTS探测器之类的工具,看一下实际存储在内存中的内容。

答案 1 :(得分:3)

您需要探索代码以查看内存泄漏的位置。这可能发生在您正在进行的事件中(手动或自动),导致明显超出范围的对象无法正确处理。

答案 2 :(得分:3)

在C#(和Java)中,只要您具有对象的引用,程序环境就会假定您仍在使用该对象。调用空闲内存只会释放未使用的对象。关键是停止使用该对象。

你有类似的东西:

Object mine = new Object();

关键是你还需要:

mine = null;

表示不再使用“我的”对象。通常这些问题不会发生在这样的代码块中,因为一旦离开块,变量就不再可访问了:

public void process() {
  Object mine = new Object();
}

通常这些问题发生在像这样的代码块中,因为Collection会随着时间的推移累积对象:

static List tasks = new ArrayList();

public void process(String item) {
  tasks.add(item);
}

关键是如果没有相应的tasks.remove(item),列表将保留对永久阻止垃圾收集工作的项目的引用。