我有一个从网上下载网页的抓取工具(使用C#)。
该应用程序需要更多虚拟内存,
即使我处理每个对象,甚至使用GC.Collect() .
这个,有10个线程,每个线程都有一个下载页面的套接字。
在每个帖子中,我有一个byte[] buffer
来存储页面的内容,并且有
我存储在其中的string str_content
,字符串中的页面内容。
我有一个Sytem.Timer
,如果每个线程都已经停止,则每3秒钟一次,
分配新线程并启动它。
我使用dispose方法甚至在我的应用程序中使用GC.Collect()
,但在3小时内我的应用程序需要
虚拟内存500 MB(Process Explorer中专用字节500 MB)。然后我的系统
将挂起,我应该重新启动我的电脑。
如果我将byte[]
和string
指定为null,那会有点粗鲁吗?
我有什么方法可以用来释放虚拟内存吗?
谢谢。
答案 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)
,列表将保留对永久阻止垃圾收集工作的项目的引用。