我正在调试进程核心转储,我想进行设计更改。 C ++进程使用eSQL / C连接到informix数据库。
目前,该应用程序使用一个查询,该查询从数据库中获取超过2lacs的行。对于每一行,它使用new
创建动态内存并处理结果。它有时会导致Out of memory
错误,可能是因为内在的内存泄漏。
我正在考虑一个选项,通过该选项,我一次只能从数据库中查询500行,分配动态内存并对其进行处理。一旦取消分配,然后加载下一个500,依此类推。但这会增加数据库查询的数量,即使一次所需的动态内存减少了。
所以我的问题是这个选项是否是一个可扩展的解决方案。 更多数据库调用是否会降低应用程序的可伸缩性?
答案 0 :(得分:1)
取决于查询。
此刻您的单个电话需要一定的时间才能返回所有200k行。假设时间与数据库中的行数成比例,称之为n
。
如果结果是新的较小的呼叫仍然需要与数据库中的行数成比例的时间,那么您的整体操作将花费与n^2
成比例的时间(因为您必须以n / 500
费用进行n
次呼叫。这可能不具有可扩展性。
因此,您需要确保在数据库中具有正确的索引(或者更可能的是,确保根据已经编入索引的某个字段的顺序将行划分为500个组)较小的调用花费的时间大致与返回的行数成比例,而不是DB中的行数。然后它可能是可扩展的。
无论如何,如果你确实有内存泄漏,那么它们就是bug,它们不是“固有的”,它们应该被删除!
答案 1 :(得分:0)
数据库调用肯定会花费更多的动态内存分配(虽然价格昂贵)。如果无法修复内存泄漏,则应尝试此解决方案并调整行数以获取最大效率。
无论如何,内存泄漏是一个巨大的问题,你的解决方案只是暂时的。你应该尝试一下智能指针。
答案 2 :(得分:0)
除非您正在处理少量记录,否则在处理过程中将所有记录保存在内存中的速度不是很高。鉴于当前的解决方案已经失败,分页肯定会带来更好的可伸缩性。虽然多次往返会因网络延迟而导致更长的延迟,但是分页将允许您处理更多的记录。
那就是说,你绝对应该解决内存泄漏错误,因为你仍然会遇到内存不足的异常,泄漏会花费更长的时间来累积到异常发生的地方。
此外,您应该确保在分页时不要打开任何游标,否则可能会导致其他游标出现阻塞问题。您应该创建一个一次只返回一页数据的SQL语句。
答案 3 :(得分:0)
首先确定您是否有内存泄漏并修复它们。
内存泄漏无法很好地扩展。
其次,分配动态内存通常比数据库访问快得多 - 除非您分配大量内存并需要增加堆。
如果你要求很多(100k以上的行)来执行处理 - 首先要问自己为什么有必要获取所有这些 - 可以修改SQL以执行基于的处理标准 - 如果您澄清处理过程,我们可以提供更好的建议。
获取和处理大量数据需要经过适当考虑,以确保其可以很好地扩展。