GC.Collect()应该定期调用吗? [英] Should GC.Collect() be called regularly?

查看:229
本文介绍了GC.Collect()应该定期调用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发布了一篇关于日志文件阅读器由于内存不足错误而失败的文章> 内存不足错误归档日志文件



在我有机会尝试更简单的方法之前(调用日志文件的名称一个日期以防止归档),这显然意味着重写方法等,我第一次尝试垃圾收集选项,因为我从来没有使用它,例如GC.Collect()。

如果在尝试读取日志文件内容时发生内存错误,并且它似乎释放了一半内存,例如从一个内存在这个过程中使用的调试文件(因为日志文件显然没有动作,所以这是为了帮助我在调试后进行调试)我得到了昨晚归档过程的响应。

 尝试存档
使用ReadFileString获取当前文件的内容(这是我写的自定义流读取器方法,您可以在原始文章中看到)
当前文件!
TRY / CATCH - 内存不足异常 - 尝试GC.Collect()
收集前使用的内存:** 498671500 **
收集后使用的内存:** 250841460 **
用ReadFileString再试一次
我们有多少内容?内容长度是** 123595955 **
我们有来自旧日志文件的内容

所以GC.Collect似乎修复了读取文件的问题。



然而,我只是想知道从这个调试中释放了什么样的内存,因为它正在移除当我调用GC.Collect()时,内存为247.83MB

因此,我想知道什么样的对象或内存正在释放,因为我认为.NET应该具有良好的内置垃圾收集功能,并且如果它正在使如果我经常频繁地调用GC.Collect()来释放内存或生成的内存量,这是因为它在第一次尝试将日志文件读入内存时失败了,那么随着时间的推移会出现多少可释放的内存?



很明显,它已经有一段时间没有处理大文件了,直到我尝试了以前从未使用过的GC.Collect,所以我只是想知道内存来自哪里,当它被正常收集,并且它应该在其他地方被调用。

这是一个windows服务应用程序,该应用程序嵌入到一个使用许多HTTP调用第三方API的DLL中JSON使用多个定时器来控制每个需要运行的工作。因此,它会不断运行,除非我手动停止服务。



因此,我应该每晚调用一次GC.Collect(),就像从其他文章中人们所说的一样把垃圾收集留给系统,但是从这个实例中它帮助快速解决了抛出内存错误的问题(我有一个14GB的64位计算机,它正在运行)。

解决方案

垃圾收集器通常会收集不再使用和自动引用的托管对象。通常不需要(或不应该)手动调用 GC.Collect()方法。
但是,例如(在这种情况下)当你打电话时:

  queue.Dequeue(item)... 

在一个长循环中,没有指向被删除对象的指针或变量,但是因为它仍然在方法范围内,垃圾收集器不会收集它,直到内存变得非常低。如果您处于这种危急情况,您可以手动调用它。


I recently posted an article about a log file reader failing due to out of memory errors > Out of memory error archiving a log file

Before I had a chance to try the simpler methods (calling the log file a name with a date in to prevent archiving anyway) which obviously would have meant rewriting the method etc, I first tried the Garbage Collection option as I had never used it e.g GC.Collect().

This was placed in the first try/catch if a memory error was thrown whilst trying to read the log files contents and it seems to free up half the memory e.g from a debug file used during this process (as the log file is obviously out of action so this is to help me debug after the fact) I get this response from last nights archive process.

Attempt Archive
Take contents of current file with ReadFileString  (this is my custom stream reader method I wrote which you can see in the original article)
Taken contents of current file!
In TRY/CATCH - Out of Memory Exception - Try GC.Collect()
Memory used before collection: **498671500**
Memory used after collection: **250841460**
Try again with ReadFileString
How much content have we got? Content Length is **123595955**
We have content from the old log file

So GC.Collect seems to fix the read file issue.

However I am just wondering WHAT kind of memory it is freeing up as from this debug as it is removing 247.83MB of memory when I call GC.Collect().

Therefore I would like to know what sort of objects or memory it is freeing up as I thought .NET was supposed to have good inbuilt garbage collecting and if it is making this much "freeable" memory over time should I be regularly calling GC.Collect() every so often to free up memory or this amount of memory generated just because it failed at the first attempt to read the log file into memory?

Obviously it hasn't been working with large files for some time now until I tried the GC.Collect which I have never used before so I was just wondering where the memory was coming from, when it gets collected normally, and should it be called elsewhere.

This is a windows service app which nooks into a DLL that makes many HTTP calls to a 3rd party API using JSON over the day using multiple timers to control each job it needs to run. Therefore it runs constantly unless I manually stop the service.

So should I call a GC.Collect() once a night anyway just as good practise as from other articles people say to leave Garbage collection to the system but from this instance it has helped to quickly solve a problem where Out of Memory errors were being thrown (I have a 14GB 64 bit computer that this is running on).

解决方案

The garbage collector usually collects managed objects which are not used and referenced anymore automatically. Usually there is no need to (or should not) call GC.Collect() method manually. But for example (in this case) when you are calling:

 queue.Dequeue(item)... 

In a long loop, there is no pointer or variable pointing to removed object, but because it is still within method scope the garbage collector does not collect it until memory becomes very low. You can call it manually if you are in critical situation like this.

这篇关于GC.Collect()应该定期调用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆