【问题标题】:Read of text file never being released from memory读取文本文件永远不会从内存中释放
【发布时间】:2020-01-06 06:54:32
【问题描述】:

我将 .NET Framework 4.6.2 (VB) 用于 Windows 服务。我正在使用 NLog 毫无问题地编写日志文件。我现在添加了一个日志查看器实用程序,它将显示日志文件的最后 100 行。我已经使用了各种方法来读取文件,但似乎无法逃避我最终需要遍历整个文件以获取所需行的现实。这不是问题。

我遇到的问题是,在我读完文件后,它似乎永远不会从内存中释放出来。当我启动我的应用程序时,它使用了大约 16MB 的内存。读取(最多 10MB 的文件)后,它使用了大约 38.5MB。即使是清除 List(Of String) 或强制垃圾回收之类的事情也永远不会完全释放内存。

我使用的可能是最简单的阅读版本:

Dim LogEntries As List(Of String) = System.IO.File.ReadLines(LogFile).ToList()
LogEntries.Clear()

我在 ReadLinesLogEntries.Clear() 步骤之间执行其他任务,但即使我只使用上面显示的行,问题仍然存在。

我希望在清除 LogEntries 列表时将内存使用量返回到大约 16MB,但我能够得到的最低值(在GC.Collect() 之后)大约是 22MB。谁能给我解释一下?

【问题讨论】:

  • 次要附录 - 我只是让我的应用程序坐了大约 40 分钟,最终释放了内存。我想我的问题现在变成了,我必须立即发布哪些选项?

标签: vb.net .net-4.6.2


【解决方案1】:

调用ReadLines 的全部意义在于它不会同时读取每一行。如果您随后在结果上调用ToList,则强制它等待直到读取所有行。这很愚蠢。如果您想要最后 100 行,那么您别无选择,只能阅读全部内容,但保留所有内容是没有意义的。

Dim lines = File.ReadAllLines(filePath)

lines = lines.Skip(lines.Length - 100).ToArray()

第一行将整个文件读入 String 数组,然后第二行创建仅包含最后 100 个元素的第二个数组并丢弃第一个数组。

另一个以牺牲性能为代价减少内存消耗的选项是:

Dim lines As New List(Of String)

Using reader As New StreamReader(filePath)
    Do Until reader.EndOfStream
        lines.Add(reader.ReadLine())

        If lines.Count > 100 Then
            lines.RemoveAt(0)
        End If
    Loop
End Using

【讨论】:

  • 感谢您的反馈 - 这对我来说是阅读文件的一种教育 - 但刚刚测试过它似乎与我在内存占用方面使用的方法相同。我遇到的问题的本质不在于读取的性能,而在于我的应用程序的内存使用量在读取文件后增加了一倍以上,
  • 在您编辑之后,我对 StreamReader 方法进行了一些试验,发现内存问题实际上与读取文本文件无关,而是与 List (Of String) 有关。我已经调整了您推荐的方法来寻找解决方案。
猜你喜欢
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多