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