【发布时间】:2016-10-24 21:19:25
【问题描述】:
// C:\logs\AzureSDK.log is ~2.5GB file
IEnumerable<string> lines = File.ReadLines(@"C:\logs\AzureSDK.log").SkipWhile(line => false);
Console.WriteLine(string.Join("\n", lines));
return;
这显然 在我得到 OOM 之前不会返回迭代器并在内部分配内存。在SkipWhile 谓词中返回true 不会导致这种情况并按预期完成(对MB 执行期间的内存使用情况)
根据文档、方法签名和常识,SkipWhile 必须返回一个迭代器,而不是将所有数据加载到内存中。
机器信息
Microsoft Windows [Version 10.0.14393]
Target 4.5.2, AnyCPU, Release
VS 2015 Update 3
NET 4.6.01586
想法?我一定是在做一些愚蠢的事情,但不确定是什么
UPD:愚蠢的事情是我忘记的 string.Join,它附加到单个 StringBuilder 将所有行加载到内存中。
我还检查了 SkipWhile 来源,它显然非常好:
public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
return SkipWhileIterator<TSource>(source, predicate);
}
static IEnumerable<TSource> SkipWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) {
bool yielding = false;
foreach (TSource element in source) {
if (!yielding && !predicate(element)) yielding = true;
if (yielding) yield return element;
}
}
【问题讨论】:
-
SkipWhile确实返回一个枚举数。但是随后您使用string.Join连接所有内容,因此最终将整个文件加载到内存中 -
我知道我一定是个笨蛋,谢谢
-
不漏,只是使用^_^
-
问题是明显的编码错误的结果,并不反映标题/正文中说明的原始问题,因此令人困惑
标签: c# linq memory-leaks