Can" pragma pack 1"有助于避免堆碎片?

时间:2014-05-06 07:03:58

标签: c++ c memory-management memory-fragmentation

在我的程序中,我看到一些居民规模增加。我想这是因为堆碎片。 所以我打算使用#pragma pack 1。 它会减少堆碎片吗?

它会有其他一些开销吗?

我要不要去做?

5 个答案:

答案 0 :(得分:10)

有一种经过充分证明的技术称为Memory pools。它专门用于减少内存碎片并帮助解决内存泄漏问题。它应该用于内存碎片成为程序功能瓶颈的情况。

'pragma pack 1'对避免堆碎片没有帮助。

'pragma pack 1'用于从结构中删除填充字节,以帮助在程序之间传输二进制结构。

答案 1 :(得分:6)

这就是操作系统的工作原理。释放一些已分配的内存时,它不会从进程内存映射中取消映射。这是一种来自操作系统的优化,以防过程需要再次分配更多内存,因为操作系统不必将新映射添加到进程内存映射。

答案 2 :(得分:5)

#pragma pack N告诉编译器以特定方式对齐结构成员,使用(N-1)个字节填充。例如,如果N为2,则每个char将占用2个字节,一个分配,一个填充。当N为1时,将没有填充。这将有更多的碎片,因为如果结构说一个char和一个int,总共5个字节就会有奇数个字节。 检查:#pragma pack effect

答案 3 :(得分:4)

打包结构可能不会对堆碎片产生太大影响。当存在重复的分配模式和释放内存时,通常会发生堆碎片。这里有两个问题,一个问题是虚拟地址空间被分割,另一个问题是物理4k页面最终会有未使用的间隙,随着时间的推移消耗越来越多的内存。微软通过偶尔重新打包内存的.net框架解决了4k页面的问题,但是在重新打包期间“暂停”了.net应用程序。我不确定每天24小时/每周7天运行的服务器应用程序如何处理这个问题而不必处理暂停,除非他们偶尔会分出一个新进程来接管服务器端然后关闭旧服务器使用一组新页面刷新新进程虚拟地址空间的进程。

答案 4 :(得分:4)

如果您特别关注堆碎片,那么您可能希望增加结构打包。这会(偶尔)导致不同的结构分布在较少的不同大小的桶之间,并且当它们占据先前释放的稍大的结构的空间时,减少分配的可能性而留下不可用的间隙。

但这不太可能是你真正关心的问题。另一个答案指出,操作系统不会立即回收释放的内存,这可能会影响该进程的内存使用量。