-3

我正在调试一个进程核心转储,我想做一个设计更改。C++ 进程使用 eSQL/C 连接到 informix 数据库。

目前,该应用程序使用从数据库中获取超过 2lacs 行的查询。new对于每一行,它使用并处理结果创建动态内存。它有时会导致Out of memory错误,可能是由于固有的内存泄漏。

我正在考虑一个选项,我一次只能从数据库中查询 500 行,分配动态内存并处理它。一旦它被取消分配,然后加载下一个 500,依此类推。但这会增加数据库查询的数量,即使一次所需的动态内存减少了。

所以我的问题是这个选项是否是一个可扩展的解决方案。更多的数据库调用是否会使应用程序的可扩展性降低?

4

4 回答 4

1

取决于查询。

您此时的单个调用需要一定的时间才能返回所有 200k 行。假设时间与数据库中的行数成正比,称之为n

如果事实证明您的新的、较小的调用仍然需要与数据库中的行数成正比的时间,那么您的整体操作将需要与成正比的时间n^2(因为您必须以每次n / 500调用的成本进行调用n)。这可能不可扩展。

因此,您需要确保数据库中有正确的索引(或者更可能的是,确保根据已索引的某些字段的顺序将行分成 500 组),以便较小的调用所花费的时间大致与返回的行数成正比,而不是与数据库中的行数成正比。那么它可能是可扩展的。

无论如何,如果您确实有内存泄漏,那么它们就是错误,它们不是“固有的”,应该将它们删除!

于 2012-06-25T08:32:38.620 回答
0

除非您正在处理少量记录,否则在处理时将所有记录保存在内存中的可扩展性不是很高。鉴于当前的解决方案已经失败,分页肯定会带来更好的可扩展性。虽然多次往返会由于网络延迟而导致更大的延迟,但分页将允许您处理更多的记录。

也就是说,您绝对应该解决内存泄漏错误,因为您仍然会遇到内存不足的异常,泄漏累积到发生异常的点需要更长的时间。

此外,您应该确保在分页时不要打开任何游标,否则可能会导致其他人出现阻塞问题。您应该创建一次只返回一页数据的 SQL 语句。

于 2012-06-25T08:34:26.370 回答
0

首先确定您是否有内存泄漏,如果有,请修复它们。

内存泄漏不能很好地扩展。

其次,分配动态内存通常比访问数据库快得多——除非您分配大量内存并需要增加堆。

如果您请求很多(超过 100k 行)来执行处理 - 首先问自己为什么需要获取所有这些- 是否可以修改 SQL 以根据标准执行处理 - 如果您澄清我们可以提供的处理关于如何做到这一点的更好的建议。

获取和处理大量数据需要适当的考虑以确保其能够很好地扩展。

于 2012-06-25T08:39:31.523 回答
0

DB 调用肯定比动态内存分配花费更多(尽管两者都很昂贵)。如果您无法修复内存泄漏,您应该尝试此解决方案并调整行数以获取最大效率。

无论如何,内存泄漏是个大问题,您的解决方案只是暂时的。您应该尝试使用智能指针。

于 2012-06-25T08:29:29.157 回答