我目前正在从事一项医学图像处理项目,需要大量的内存。有什么方法可以避免堆碎片和加速已加载到内存中的图像数据的访问速度?
应用程序是用C++编写的,运行在Windows XP上。
编辑: 应用程序对图像数据进行一些预处理,如重新格式化、计算查找表、提取感兴趣的子图像等。在处理期间,应用程序需要约2 GB的RAM,其中大约1.5 GB可用于图像数据。
我目前正在从事一项医学图像处理项目,需要大量的内存。有什么方法可以避免堆碎片和加速已加载到内存中的图像数据的访问速度?
应用程序是用C++编写的,运行在Windows XP上。
编辑: 应用程序对图像数据进行一些预处理,如重新格式化、计算查找表、提取感兴趣的子图像等。在处理期间,应用程序需要约2 GB的RAM,其中大约1.5 GB可用于图像数据。
我猜你在使用一些非托管的东西,因为在托管平台上系统(垃圾回收器)会处理碎片问题。
对于 C/C++,你可以使用其他分配器,而不是默认的分配器。(关于分配器已经有一些线程在 Stack Overflow 上了。)
此外,你还可以创建自己的数据存储。例如,在我目前正在工作的项目中,我们有一个自定义存储池,用于位图(我们将它们存储在一个大的连续内存块中),因为我们有很多这样的位图,并且我们跟踪堆的碎片,并在碎片太大时对其进行整理。
你可能需要实现手动内存管理。图像数据的生命周期长吗?如果不是,那么你可以使用Apache Web服务器使用的模式:分配大量内存并将它们包装到内存池中。将这些池作为函数的最后一个参数传递,以便它们可以使用池来满足分配临时内存的需求。一旦调用链完成,池中的所有内存都不再使用,因此您可以清除内存区域并再次使用它。分配很快,因为它们只意味着将值添加到指针中。释放非常快,因为您将一次性释放非常大的内存块。
如果您的应用程序是多线程的,则可能需要将池存储在线程本地存储中,以避免跨线程通信开销。
如果您能够准确地确定那些可能会分配大块内存的位置,您可以(在Windows上)直接调用VirtualAlloc而不是通过内存管理器。这将避免在普通内存管理器中出现碎片。
这是一个简单的解决方案,不需要使用自定义内存管理器。