在我的程序中,我看到一些居民规模增加。我想这是因为堆碎片。所以我打算用#pragma pack 1
. 它会减少堆碎片吗?
它会产生其他一些开销吗?
我去还是不去?
在我的程序中,我看到一些居民规模增加。我想这是因为堆碎片。所以我打算用#pragma pack 1
. 它会减少堆碎片吗?
它会产生其他一些开销吗?
我去还是不去?
有一种经过充分验证的技术称为内存池。它专为减少内存碎片和帮助解决内存泄漏而设计。它应该用于内存碎片成为程序功能瓶颈的情况。
'pragma pack 1' 对避免堆碎片没有帮助。
'pragma pack 1' 用于从结构中删除填充字节,以帮助在程序之间传输二进制结构。
这只是操作系统的工作方式。当您释放已分配的一些内存时,它不会从进程内存映射中取消映射。这是操作系统的一种优化,以防进程需要再次分配更多内存,因为操作系统不必向进程内存映射添加新映射。
#pragma pack N
, 告诉编译器以特定方式对齐结构的成员,并使用 (N-1) 字节填充。例如,如果 N 为 2,则每个 char 将占用 2 个字节,一个分配,一个填充。N 为 1 时,将没有填充。这将有更多的碎片,因为如果结构有一个 char 和一个 int,总共有 5 个字节,则会有奇数个字节。检查:#pragma pack 效果
如果您特别关心堆碎片,那么您可能需要增加结构打包。这将(偶尔)导致不同的结构分布在较少的不同大小的存储桶之间,并降低分配在占用先前释放的稍大结构的空间时留下不可用间隙的可能性。
但这不太可能是您真正关心的问题。正如另一个答案指出的那样,操作系统不会立即回收释放的内存,这会影响进程的明显内存使用情况。
打包结构可能不会对堆碎片产生太大影响。当存在重复的分配和释放内存模式时,通常会发生堆碎片。这里有两个问题,一个问题是虚拟地址空间变得碎片化,另一个问题是物理 4k 页面最终会出现未使用的间隙,随着时间的推移消耗越来越多的内存。Microsoft 使用它的 .net 框架解决 4k 页面问题,该框架偶尔会重新打包内存,但通过在重新打包期间“暂停”.net 应用程序来实现。我不确定每天 24 小时/每周 7 天运行的服务器应用程序如何处理这个问题而不必处理暂停,