过去,当我处理长时间运行的C ++守护进程时,我不得不处理堆碎片问题。保持我的大量分配池的技巧是必要的,以防止耗尽连续的堆空间。
这仍然是64位地址空间的问题吗? Perf对我来说不是一个问题,所以我宁愿简化我的代码而不再处理像缓冲池这样的事情。有没有人有关于这个问题的经验或故事?我正在使用Linux,但我想很多相同的问题都适用于Windows。
答案 0 :(得分:9)
这仍然是64位地址空间的问题吗?
不,这还不是问题。
你是对的,这是32位系统的一个问题,但它不再是64位系统的问题。
虚拟地址空间在64位系统上是如此之大(目前x86_64处理器上的时间为2 ^ 48字节,并且随着新的x86_64处理器的出现,设置逐渐增加到2 ^ 64),这是不连续的由于碎片造成的虚拟地址空间实际上是不可能的(除了一些非常人为的极端情况)。
(由于64是“仅”双32的事实引起的直觉的常见错误,这导致人们认为64位地址空间大约是32位地址的两倍。实际上是完整的64位地址空间是32位地址空间的40亿倍。)
如果它将你的32位守护进程一周分段到一个无法分配x字节块的阶段,那么另一种方式就是它至少需要一千多年来分割今天的x86_64处理器48位地址空间,并且需要 8000万年来分割未来计划的完整64位地址空间。
答案 1 :(得分:1)
在64位下,堆碎片与32位下的碎片一样多。如果您使用不同的生命周期进行大量请求,那么您将获得一个碎片堆。不幸的是,64位操作系统并没有真正帮助解决这个问题,因为它们仍然无法真正改变可用内存的一小部分来制作更大的连续块。
如果你想处理堆碎片,你仍然必须使用相同的旧技巧。
64位操作系统在这方面可以提供帮助的唯一方法是,如果有足够大的内存“足够大”,你就永远不会将其分段。
答案 2 :(得分:0)
如果您的进程真正需要千兆字节的虚拟地址空间,那么升级到64位确实可以立即消除对变通方法的需求。
但值得研究一下您希望您的流程使用多少内存。如果它只在一个千兆字节或更小的区域内,那么即使是疯狂的碎片也不会让你耗尽32位地址空间 - 内存泄漏可能是问题所在。
(顺便说一下,Windows更具限制性,因为它在操作系统的每个进程中保留了不合理的地址空间量。)