我有一个应用程序,有时会利用大量数据。用户可以选择加载图形显示中使用的许多文件。如果用户选择的数据多于操作系统可以处理的数据,则应用程序会很难崩溃。在我的测试系统上,这个数字大约是2 GB的物理RAM。
处理这种情况的好方法是什么?我从新的并尝试陷阱中得到了“坏分配”,但我仍然遇到了崩溃。我觉得好像我正在艰难的水域中加载这么多数据,但这个应用程序需要处理这种大数据负载。
编辑:我现在正在32位Windows系统下进行测试,但该应用程序将运行在各种版本的Windows,Sun和Linux上,大多数是64位但是大约32位。
错误处理不强:它只是用一个try catch块包装主实例化代码,catch捕获每个另一个对等方的抱怨,即每次都无法捕获bad_alloc。
我认为你们是对的,我需要一个内存管理系统,它不会将所有这些数据加载到RAM中,它就像是它。
Edit2:路德说得最好。谢了,兄弟们。现在,我只需要一种方法来防止崩溃,并且应该可以进行适当的异常处理。但在未来,我将实施该接受解决方案。
答案 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。
听起来像是:
为避免达到极限,您需要:
答案 2 :(得分:1)
如何维护标头表而不是加载整个数据。在用户请求数据时加载实际页面。 还使用一些减少文件大小的数据压缩算法(如7zip,znet等)。 (在我的项目中,他们将大小从200MB缩小到2MB)
答案 3 :(得分:1)
我之所以提到这一点是因为上面只是简单提到过,但似乎“文件分页系统”可能是一个解决方案。这些系统通过将文件分成几部分来读取“块”中的大型数据集。一旦写完,他们通常“只是工作”,你希望不再需要修补它们。
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位可能更容易。