在c+中检测堆碎片的可移植方法+;在运行时? 我正在编写一个基于Qt的C++应用程序,我需要能够检测内存碎片,以检查当前系统是否能够实际地支持内存加载:程序加载一个大的图像(15/21兆像素是标准的)在内存中,然后对它执行一些过滤(W/稀疏矩阵)。 例如,我在Windows中遇到内存碎片问题,VMMap在这方面很有帮助:问题是一些dll(Wacom平板电脑“wintab32.dll”和UltraMon应用程序)没有重新定位,因此正在进程的0x10000000-0x30000000 VA处拆分地址空间

在c+中检测堆碎片的可移植方法+;在运行时? 我正在编写一个基于Qt的C++应用程序,我需要能够检测内存碎片,以检查当前系统是否能够实际地支持内存加载:程序加载一个大的图像(15/21兆像素是标准的)在内存中,然后对它执行一些过滤(W/稀疏矩阵)。 例如,我在Windows中遇到内存碎片问题,VMMap在这方面很有帮助:问题是一些dll(Wacom平板电脑“wintab32.dll”和UltraMon应用程序)没有重新定位,因此正在进程的0x10000000-0x30000000 VA处拆分地址空间,c++,memory,heap,detect,fragmentation,C++,Memory,Heap,Detect,Fragmentation,我想让应用程序对碎片问题有所了解,并想知道是否已经存在提供VMMAP提供的信息的跨平台(linux/mac/win32)方法。简短回答:没有可移植的方法 更详细的回答:堆是如何实现的以及它是如何工作的,这是实现的一个细节,在平台、std库和操作系统之间有很大的不同。您必须为每个实现创建一个不同的版本-如果提供,该实现将为您提供一个API来钩住它。(我认为你针对的三个平台都应该如此。)我认为你过于悲观了。2100万像素,即使假设颜色深度为16位且大小相等的alphachannel也只需要168 M

我想让应用程序对碎片问题有所了解,并想知道是否已经存在提供VMMAP提供的信息的跨平台(linux/mac/win32)方法。

简短回答:没有可移植的方法


更详细的回答:堆是如何实现的以及它是如何工作的,这是实现的一个细节,在平台、std库和操作系统之间有很大的不同。您必须为每个实现创建一个不同的版本-如果提供,该实现将为您提供一个API来钩住它。(我认为你针对的三个平台都应该如此。)

我认为你过于悲观了。2100万像素,即使假设颜色深度为16位且大小相等的alphachannel也只需要168 MB。32位系统上的可用地址空间以GB为单位

这能满足您的需要吗

bool is_contiguous_freestore_available(size_t max)
{
   char* tst = new(std::nothrow) char[max];
   if (tst == null)
      return false;

   delete[] tst;
   return true;
}

要挑剔:堆的存在是实现细节,C++指的是自由仓库。你是对的,但是我故意这样做,因为“堆”似乎是一个更普遍接受的术语;这不仅仅是术语上的差异。免费商店根本不需要是堆。不过,实现决定解决内存分配请求。由于精度是必须的,因此图像在内存中用浮点值(32位)表示,并且始终有三个通道(RGB或CiELab)导致252MB,但这不是重点。有时,应用程序启动时最大的可分配块为1.4Gb,有时仅为500Mb,而在较低VA处导致大部分碎片的dll是在0x10000000处加载的“wintab32.dll”。32位系统上的可用地址空间是以GB为单位的,但如果3gb的总空闲空间是以小块为单位的,这并不重要,碎片会导致4gb ram机器上的错误分配……不幸的是,似乎一旦DLL以0x10000000的速度加载,在此VA附近重新定位其他所有DLL:禁用Wacom平板电脑可以使其他DLL达到上限,但每当使用下限时,其他DLL(如uxtheme.DLL)就会在其附近加载。如果您不介意更改DLL,可以更改其首选基。0x10000000现在是一个特别糟糕的默认值。没错,这是一个非常糟糕的选择,不幸的是,这个DLL无法重新设置基址(rebase-v-b 0x10000000 wintab32.DLL说它不能重新设置基址)。不太可能,因为我想检测这种情况,尽管“正常”,但这样做可能会很好地分割内存本身。