读取永远不会从内存中释放的文本文件

Read of text file never being released from memory

我正在为 Windows 服务使用 .NET Framework 4.6.2 (VB)。我正在使用 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 列表时 return 内存使用量大约为 16MB,但我能够得到的最低内存(在 GC.Collect() 之后)约为 22MB .谁能给我解释一下?

调用 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