【问题标题】:Limit Virtual Memory space for malloc()限制 malloc() 的虚拟内存空间
【发布时间】:2012-05-14 11:21:31
【问题描述】:

我编写了自己的 my_malloc() 函数来管理自己的物理内存。在我的应用程序中,我希望能够同时使用 libc malloc() 以及我自己的 my_malloc() 函数。所以我需要对虚拟地址空间进行分区,malloc 应该总是分配一个虚拟地址,只有当它来自其专用池时,与 my_malloc() 相同。我无法限制堆大小,我只需要保证 malloc() 和 my_malloc() 永远不会返回相同/重叠的虚拟地址。

谢谢!

【问题讨论】:

  • 管理自己的物理内存?你确定这就是你的意思吗?
  • 预先用malloc()分配由my_malloc()管理的内存。

标签: c malloc virtual memory-address


【解决方案1】:

一种可能性是在启动时让my_malloc() 调用malloc() 预先分配一个大内存池,然后将该内存分配给它的调用者并相应地对其进行管理。但是,完整的实现需要处理垃圾收集和碎片整理。

另一种可能性是让my_malloc() 在每次需要分配内存时调用malloc() 并简单地处理您感兴趣的任何“簿记”方面,例如分配的块数、释放的块数、最大未完成的块,总分配的内存,。这是迄今为止更安全、更有效的机制,因为您将所有“硬”操作传递给malloc()

【讨论】:

    【解决方案2】:

    一个答案是让您的my_malloc 使用malloc 分配的内存。使用足够大的块将主要实现这一点;然后在每个块中,您的版本将维护自己的结构并将其部分分配给调用者。

    这变得很棘手,因为您不能依赖扩展您的版本的整个可用空间,就像您从 sbrk 或类似地址获取内存时那样。所以你的版本必须维护几个块。

    【讨论】:

      【解决方案3】:

      保留一大块虚拟地址空间,并将其作为my_malloc() 分配的池。一旦您从操作系统中保留了一个大的连续内存区域,那么对malloc() 的后续调用就必须来自其他地方。

      例如on Windows,您可以使用VirtualAlloc() 预留一个256mb 的空间块。在您通过后续调用“提交”它之前,实际上不会分配内存,但它会保留后续 malloc() 不会使用的地址范围(例如 0x4000000-0x5000000)。然后您的my_malloc() 可以根据要求提交超出此保留范围的块,并按您编写的任何分配方案细分它们。

      有人告诉我the equivalent Linux call is mmap()。 (编辑:我之前说过“kmalloc 或 vmalloc,取决于您是否需要内存物理上连续”,但这些是内核级函数。 )

      我们在我们的应用程序中使用这种机制将特定大小的所有分配重定向到我们自己的自定义池块分配器中,以提高速度和效率。除此之外,它还允许我们在certain specific sizes 中保留more efficient for the CPU to handle 的虚拟页面。

      【讨论】:

      • kmalloc 等是内核空间函数;它们与应用程序无关。 OP想要的功能是mmap。或者,OP 可以只使用真正的malloc 来获取my_malloc 的大块来分配。
      • @R.. 我想我太习惯于编写嵌入式内核级代码了!我已经确定了答案。
      【解决方案4】:

      如果您在程序开始附近添加一个mmap(2) 调用,您可以使用您需要的任何地址分配尽可能多的内存(请参阅提示,通常留下NULL供操作系统立即确定);这将阻止malloc(3) 或任何其他内存分配例程获取这些特定页面。

      不用担心内存使用;由于现代系统非常乐意过度使用,因此您只需使用几百 KB 的内核空间来处理页表。还不错。

      【讨论】:

      • 过度使用在这里不是一件好事。 OP 所做的全部目的是确保内存在以后需要时可用。最好确保禁用过度使用 (echo "2" > /proc/sys/vm/overcommit_memory)
      • @R..:哦?我以为他只是想要 他的 内存和 malloc 的内存使用不同的虚拟内存地址范围。你可能是对的——如果他这样做是为了打败过度使用,那么肯定必须采取措施。仅仅overcommit_memory 是不够的; overcommit_ratio 也必须修改。
      • overcommit_memory 一个人就足够了; overcommit_ratio (50%) 的默认值,事实上,任何远离接近 100% 的边界都可以安全地避免 OOM。
      • @R..:谢谢!我一直在假设需要更接近0 的东西。
      • 50% 意味着内核永远不会允许提交费用(基本上,分配的内存量有可能存储未备份在磁盘上的数据)超过总物理内存的 50%(包括交换)。请记住,如果您在内存中没有足够的空间来容纳相当数量的共享代码页(不计入提交费用)和文件系统缓存/缓冲区,那么系统性能将非常糟糕,只要 50% 可能就不错了你没有太多的交换(交换大小
      猜你喜欢
      • 2011-08-09
      • 2020-05-21
      • 2012-08-02
      • 1970-01-01
      • 2023-03-17
      • 2013-06-24
      • 2013-06-04
      • 1970-01-01
      • 2015-12-16
      相关资源
      最近更新 更多