如何通过不断增长的TDictionary避免内存不足?

时间:2011-12-02 11:51:29

标签: delphi memory-management collections delphi-xe

TDictionary<TKey,TValue>使用内部数组,如果它已满,则加倍:

newCap := Length(FItems) * 2;
if newCap = 0 then
  newCap := 4;
Rehash(newCap);

这适用于中等数量的项目,但如果达到上限,则非常不幸,因为即使几乎有一半的内存仍然可用,它也可能抛出EOutOfMemory异常。

有没有办法影响这种行为?其他集合类如何处理这种情况?

1 个答案:

答案 0 :(得分:9)

您需要了解字典的工作原理。字典包含“哈希桶”列表,其中放置了您插入的项目。这是一个有限的数字,所以一旦你填满它你需要分配更多的桶,没有办法解决它。由于对象到桶的分配是基于散列函数的结果,因此您不能简单地将桶添加到数组的末尾并将内容放入其中,您需要重新分配整个块列表,重新哈希所有内容并将其放入(新)相应的存储桶中。

鉴于此行为,使字典重新分配一次的唯一方法是确保它永远不会满。如果你知道你将在字典中插入的项目数量作为参数传递给构造函数,你将完成,不再需要字典重新分配。

如果您不能这样做(您不知道字典中的项目数量),您需要重新考虑首先选择TDictionary的内容并选择一种数据结构,可为您的特定算法提供更好的折衷。例如,您可以使用二进制搜索树,因为它们通过旋转现有节点中的信息来进行平衡,无需重新分配永远