C++ Can";布拉格语包1“;有助于避免堆碎片?

C++ Can";布拉格语包1“;有助于避免堆碎片?,c++,c,memory-management,memory-fragmentation,C++,C,Memory Management,Memory Fragmentation,在我的计划中,我看到一些居民人数增加。我想这是因为堆碎片。 因此,我计划使用#pragma pack 1。 它会减少堆碎片吗 会有其他的开销吗 我该不该这么做?#pragma pack N,告诉编译器以特定的方式对齐结构的成员,并填充(N-1)字节。例如,如果N为2,则每个字符将占用2个字节,一个已分配,一个填充。N为1时,将没有填充。这将有更多的碎片,因为如果结构有一个char和一个int,那么将有奇数个字节,总共5个字节。 检查:这只是操作系统的工作方式。当您释放一些分配的内存时,它不会从进

在我的计划中,我看到一些居民人数增加。我想这是因为堆碎片。 因此,我计划使用
#pragma pack 1
。 它会减少堆碎片吗

会有其他的开销吗

我该不该这么做?

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

这只是操作系统的工作方式。当您释放一些分配的内存时,它不会从进程内存映射中取消映射。这是一种来自操作系统的优化,以防进程需要再次分配更多内存,因为这样操作系统就不必向进程内存映射添加新映射。

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

如果您特别关心堆碎片,那么您可能需要增加结构打包。这将(偶尔)导致不同的结构分布在更小的不同大小的桶之间,并降低分配在占用先前释放的稍大结构的空间时留下不可用间隙的可能性


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

有一种经过充分验证的技术称为。它是专门为减少内存碎片和帮助解决内存泄漏而设计的。它应该用于内存碎片成为程序功能瓶颈的情况

“pragma pack 1”无助于避免堆碎片


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

它实际上可能会增加堆碎片,如果堆分配器尝试在良好的本机字边界上进行分配,并且结构不再填充到良好的本机字边界。您将因错误对齐的内存访问而遭受性能损失,这可能比您尝试归档(减小对象大小)的操作更糟糕。此外,您是否检查了内存泄漏,而不是假设它是堆碎片。我用valgrind查找内存泄漏。在valgrind报告中,我没有看到任何泄漏。但是RSS正在增加,这本身就是一个问题。我建议使用特定的分配器来避免碎片。对于默认的包处理,结构中的单字符变量不会被填充,但较大的类型将被填充到与其类型对应的边界,除非8字节类型,如double或long-long,如果默认包值为4,则可能不会将其置于8字节边界上。这是一个很好的建议,尽管我想知道内存池如何帮助解决内存泄漏问题?这与c有关,而不是与c++有关。假设,您希望确保在客户机与web服务器断开连接后没有内存泄漏。如何做到这一点?当客户端连接到服务器时,您将创建一个内存池(使用OS malloc分配一个大阵列)。在客户端处理代码中,您要求内存池为对象而不是操作系统分配内存。然后客户端断开与服务器的连接,您就可以释放整个池(使用free)。例如,谷歌搜索“APR内存池”和“pjsip快速内存池”。瞧,这也是心血虫的起源地。;-)更新-Microsoft Azure包括自动“负载平衡”,根据需要在内核和/或处理器之间切换,包括在.net重新打包期间。