我的问题
在我的日志(log)中,我看到在负载测试期间记录了一些System.OutOfMemory异常错误.它们来自Dapper查询.根据堆栈跟踪,调整列表大小时会发生错误.
堆栈跟踪的顶部
System.OutOfMemoyException:引发了类型为""System.OutOfMemoyException""的异常." 在System.Collections.Generic.List
1.set_Capacity(Int32 value) at System.Collections.Generic.List
1.AddWithResize(T项目中) 在C:\projects\dapper\Dapper\SqlMapper.Async.cs:line 442中的Dapper.SqlMapper.QueryAsync[T](IDbConnection CNN,输入有效类型,命令定义命令)
被调用的代码
const string sql = $@"
SELECT [Column 1]
,[Column 2]
,[Column 3]
,[Column 4]
,[Column 5]
,[Column 6]
,[Column 7]
,[Column 8]
,[Column 9]
,[Column 10]
,[Column 11]
,[Column 12]
FROM [MyDb].[MyTable]
WHERE co = @CompanyId AND process = @Process
";
await using var connection = _dbConnectionProvider.Create(DbKey.MyDb);
var parameters = new { CompanyId = CompanyDbString(companyId), Process = process };
var command = new CommandDefinition(sql, parameters);
var results = await connection.QueryAsync<MyEntity>(command); // error happens here
return results;
有关正在加载的数据的一些信息
我查看了数据库,发现有问题的数据大小为141,846行.这些列没有什么"不寻常的"(没有巨大的文本块或类似的东西),只是一些合理的varchars、date time、int等.所有的varchars最大长度为100个字符.
为了避免不可避免的"您真的需要加载所有这些数据吗?"在萌芽状态下 comments :是的,我知道.
可能的解决方案是什么?
因此,正在加载的数据是一个相当大的数据集,但并不疯狂.我很惊讶它的内存用完了.我发现特别有趣的是,这一例外源于System.Collections.Generic.List1.set_Capacity(Int32 value)
.基于此,看起来错误是在列表调整其内部数组大小时发生的.
我对如何处理这个问题的第一个 idea 是对结果进行分页,就像这里建议的那样:https://stackoverflow.com/a/52212051
然而,我不确定这是否会奏效,因为它仍然依赖于添加到的列表.这是一个合理的担忧吗?如果是这样的话,首先获得计数并以此作为初始容量开始列出是不是一个好方法?
或者,是否存在一个比List更适合调整大小/内存的不同集合?