【问题标题】:Does new / malloc cause memory shuffling in the environment of sufficient but fragmented memory?new / malloc 在内存充足但碎片化的环境下是否会造成内存洗牌?
【发布时间】:2019-08-27 03:37:47
【问题描述】:

这只是出于好奇。

例如,假设我们用完了 8 个字节的内存中的 2 个:

[xx------]

如果我调用 new / malloc 请求 3 个字节,它应该可以正常工作,也许像这样:

[xx--xxx-]

如果我调用 new / malloc 请求另外 3 个字节,会发生什么?就可用内存而言,仍有 3 个空闲字节,即使它们不连续。然后程序会“整理”内存为新分配腾出空间吗?听起来不可能,因为我仍然会保留对现有分配的引用。

如果是这样,那么延伸到一个极端情况,如果您的内存以某种方式 最终超级碎片化(例如,每隔一个字节分配 ala [x-x-x-x- x-x-x-x-]),会这意味着尽管有 50% 的可用内存,我什至无法分配 2 个字节?

我认为平台不重要?

很抱歉这个扩展问题,但在 Java/C# 等其他语言中也会发生这种情况吗?

【问题讨论】:

  • 我认为这严重依赖于架构。
  • @FantasticMrFox:如果不是所有系统,大多数系统都有一个平面(虚拟)寻址空间。堆块是连续分配的,并通过一个简单的指针访问,因此指针运算很简单。这会导致碎片问题。
  • 对于 C/C++ 是。有时 malloc 使用 sbrk 有时它使用 mmap。在所有情况下,它都不能移动数据,因为这会使您的程序正在使用的指针无效。

标签: c++ c memory memory-management out-of-memory


【解决方案1】:

没错,内存会变得如此碎片化,以至于无法再进行分配。一个好的分配器会在可能的情况下合并释放的块,以限制碎片。

MS .NET 托管框架通过间接分配内存块来解决这个问题,即通过指向块指针的指针。这样,可以将块移动到碎片整理内存,而无需将指针更改为指针。 (框架采取了一些措施来避免并发问题,因为 .NET 有一个异步运行的垃圾收集器。)

【讨论】:

  • MS .net 框架并没有解决使用malloc() 固有的碎片问题,它只是提供了一种处理内存块的替代方法,具有非常具体的约束和一些优势。
  • @chqrlie:当然,我说的是 gcnew。它会进行碎片整理,否则双重引用将毫无用处。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 2014-01-09
  • 2013-08-14
  • 1970-01-01
  • 2011-04-15
  • 2013-06-12
相关资源
最近更新 更多