关闭。这个问题需要debugging details .它目前不接受答案。
想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。
5年前关闭。
Improve this question
我最近发布了一篇关于日志文件阅读器由于内存不足错误而失败的文章 > Out of memory error archiving a log file
在我有机会尝试更简单的方法(将日志文件命名为带有日期的名称以防止存档)之前,这显然意味着重写方法等,我首先尝试了垃圾收集选项,因为我从未使用过它,例如GC.Collect()。
如果在尝试读取日志文件内容时抛出内存错误,则将其放置在第一个 try/catch 中,并且它似乎释放了一半内存,例如在此过程中使用的调试文件中(因为日志文件显然已超出行动,所以这是为了帮助我在事后调试)我从昨晚的存档过程中得到了这个响应。
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
所以 GC.Collect 似乎解决了读取文件的问题。
然而,我只是想知道它正在从这个调试中释放什么样的内存,因为它正在删除 247.83MB 内存 当我调用 GC.Collect() 时。
因此,我想知道它正在释放什么样的对象或内存,因为我认为 .NET 应该具有良好的内置垃圾收集功能,如果随着时间的推移它会产生这么多“可释放”的内存,我应该定期调用 GC.Collect () 是否经常释放内存或仅因为在第一次尝试将日志文件读入内存时失败而生成的内存量?
显然,在我尝试之前从未使用过的 GC.Collect 之前,它已经有一段时间没有处理大文件了,所以我只是想知道内存来自哪里,何时正常收集,以及是否应该调用它别处。
这是一个 Windows 服务应用程序,它隐藏在一个 DLL 中,该 DLL 使用多个计时器来控制它需要运行的每个作业,在一天内使用 JSON 对第三方 API 进行多次 HTTP 调用。因此,除非我手动停止服务,否则它会一直运行。
所以我应该每晚调用一次 GC.Collect() 就像其他文章中人们所说的将垃圾收集留给系统一样好的做法,但从这个例子中它有助于快速解决内存不足错误的问题抛出(我有一台正在运行的 14GB 64 位计算机)。
最佳答案
首先非常仔细地检查您正在关闭(处置)所有文件对象,否则内部文件缓冲区将不会被释放,直到 GC 发现您忘记关闭文件。
如果不需要复制文件,只需重命名(FileInfo.Rename)。这是处理日志文件的正常方式。
如果您不需要处理数据,请使用 FileInfo.CopyTo或 CopyTo(Stream)方法,这就是为什么将使用合理的小缓冲区复制文本,并且永远不需要分配内存来同时保存所有文本。
如果您确实需要处理文本,请一次读取一行,这将导致创建许多小字符串,而不是一个非常大的字符串。 .net GC 非常擅长回收小生命周期的对象。 您不应将整个日志文件同时保存在内存中。创建一个返回文件中的行的自定义迭代器将是一种方法。
关于c# - 应该定期调用 GC.Collect() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36544916/