TFDQuery执行查询后,将数据载入到控件时,会按照数据库中“字段定义长度 * 返回的记录数”初始化内存数组(注意,是定义的字段长度,不是字段内容的实际长度),如果“字段定义长度 * 返回的记录数”计算出的内存达到2G,就会报Out of memory错误。
例如:
Create Table Test(iID int,cName varchar(512))
go
Insert into Test(iID,cName) Values(1,'A')
Insert into Test(iID,cName) Values(2,'B')
Insert into Test(iID,cName) Values(3,'C')
GO
Select * from Test
GO
象上述例子,每条记录实际长度是5字节(Int 4位 + Varhcar 1位),按正常理解占用内存应该是 3 * (4 + 1) = 15,但是FDQuery在加载时,不是按实际长度计算的,而是按最大长度,所以它占用的内存数是 3 * (4 + 512) = 1548,如果这个数值超过上限,就报错。
暂时没有有效的方法解决该问题,只能采用以下方法尽量规避:
1、 不要一次性返回大量的记录数
2、字符串字段长度不要随意,尽量修改为合适大小
3、查询时尽量只返回需要的字段,不要直接Select *。
4、使用分页查询
注:
该数组内存大小可能是由属性ResourceOptions.ArrayDMLSize控制的,默认值为2147483647,即2G,猜测,待确认
补充:
改为64位编译后,可以超过2G内存限制。