处理c ++中的大量数据

时间:2010-08-16 14:55:51

标签: c++ memory-management

我有一个应用程序,有时会利用大量数据。用户可以选择加载图形显示中使用的许多文件。如果用户选择的数据多于操作系统可以处理的数据,则应用程序会很难崩溃。在我的测试系统上,这个数字大约是2 GB的物理RAM。

处理这种情况的好方法是什么?我从新的并尝试陷阱中得到了“坏分配”,但我仍然遇到了崩溃。我觉得好像我正在艰难的水域中加载这么多数据,但这个应用程序需要处理这种大数据负载。

编辑:我现在正在32位Windows系统下进行测试,但该应用程序将运行在各种版本的Windows,Sun和Linux上,大多数是64位但是大约32位。

错误处理不强:它只是用一个try catch块包装主实例化代码,catch捕获每个另一个对等方的抱怨,即每次都无法捕获bad_alloc。

我认为你们是对的,我需要一个内存管理系统,它不会将所有这些数据加载到RAM中,它就像是它。

Edit2:路德说得最好。谢了,兄弟们。现在,我只需要一种方法来防止崩溃,并且应该可以进行适当的异常处理。但在未来,我将实施该接受解决方案。

6 个答案:

答案 0 :(得分:17)

STXXL库为大型数据集提供类似STL的容器。

将“大”改为“巨大”。它专为多核处理数据集而设计和优化,仅适用于TB级磁盘。这可能足以解决您的问题,或者实施可能是定制您自己的解决方案的良好起点。


很难说你的应用程序崩溃,因为在紧张的内存条件下涉及到许多小问题:你可能遇到硬地址空间限制(例如默认情况下32位Windows只有2GB的地址空间每个用户进程,这可以更改,http://www.fmepedia.com/index.php/Category:Windows_3GB_Switch_FAQ),或被OOM杀手活着吃(不是神话中的野兽:,见http://lwn.net/Articles/104179/)。

在任何情况下我都建议考虑一种将数据保存在磁盘上的方法,并将主存储器视为数据的一种Level-4缓存。例如,如果您有数据blob,那么将它们包装在一个类中,该类可以透明地在需要时从磁盘加载blob并注册到某种类型的内存管理器,它可以询问某些内存管理器。在内存条件变得无法忍受之前,blob持有者要释放他们的记忆。因此缓冲区缓存。

答案 1 :(得分:2)

  

用户可以选择加载图形显示中使用的多个文件。

通常的技巧不是直接将数据加载到内存中,而是使用memory mapping机制使文件看起来像内存。

您需要确保内存映射是以只读模式完成的,以允许操作系统在需要其他内容时将其从RAM中逐出。

  

如果用户选择的数据多于操作系统可以处理的数据,则应用程序会很难崩溃。

取决于操作系统,它是:应用程序缺少一些内存分配错误处理,或者您真正达到了可用虚拟内存的限制。

某些操作系统对应用程序堆的增长量也有一个管理限制。

  

在我的测试系统上,这个数字约为2 g物理RAM。

听起来像是:

  • 您的应用程序是32位和
  • 您的操作系统使用2GB / 2GB虚拟内存分割。

为避免达到极限,您需要:

  • 将您的应用和操作系统升级到64位或
  • 告诉OS(适用于Windows的IIRC补丁程序;大多数Linux已经拥有它)使用3GB / 1GB虚拟内存拆分。一些32位操作系统使用2GB / 2GB内存分割:内核为2GB虚拟内存,用户应用程序为2GB。 3/1拆分意味着1GB的VM用于内核,3个用于用户应用程序。

答案 2 :(得分:1)

如何维护标头表而不是加载整个数据。在用户请求数据时加载实际页面。 还使用一些减少文件大小的数据压缩算法(如7zip,znet等)。 (在我的项目中,他们将大小从200MB缩小到2MB)

答案 3 :(得分:1)

我之所以提到这一点是因为上面只是简单提到过,但似乎“文件分页系统”可能是一个解决方案。这些系统通过将文件分成几部分来读取“”中的大型数据集。一旦写完,他们通常“只是工作”,你希望不再需要修补它们。

Reading Large Files

Variable Length Data in File--Paging

下面的新链接有很好的答案。

Handling Files greater than 2 GB

搜索字词:“file paging lang:C ++”添加大于或等于2GB以上。 HTH

答案 4 :(得分:0)

不确定您是否正在使用它,但如果您使用Linux,malloc通常不会失败,operator new通常不会抛出bad_alloc。这是因为Linux会过度使用,而是在它决定系统没有足够的内存时,可能是在页面错误时终止你的进程。

请参阅:Google search for "oom killer"

您可以使用以下方法禁用此行为:

echo 2 > /proc/sys/vm/overcommit_memory

答案 5 :(得分:-1)

升级到64位CPU,64位操作系统和64位编译器,并确保有足够的RAM。

32位应用程序限制为2GB内存(无论您拥有多少物理RAM)。这是因为32位指针可以处理2 ^ 32字节== 4GB的虚拟内存。 20年前,这似乎是一个巨大的内存,所以原来的操作系统设计师为运行的应用程序分配了2GB,并保留了2GB供操作系统使用。您可以使用各种技巧来访问超过2GB的内容,但它们很复杂。升级到64位可能更容易。