我需要自定义内存分配器吗?

时间:2013-05-24 22:14:51

标签: c memory memory-management

我目前正在开发一个缓存服务器,它本身就使用了很多RAM(我在具有大量HTTP流量且两个{{3}的服务器上测试它和一个使用它来缓存内存中数据的自定义Web应用程序。

服务器显然执行了大量的malloc / realloc / free操作,这些操作很昂贵,所以我想知道是否应该使用自定义内存分配器,也许是在开始时预先分配一个大“内存池”然后使用它的东西在执行malloc / realloc时提供所请求大小的自由“片段”,并在调用free时将其标记为已释放。

我走的是正确的道路还是不是我真的需要这样的东西?有没有像这样的分配器,还是我必须编写自己的代码?

重要说明:

  • 服务器是单线程(使用多路复用),所以我没有 需要在多线程中具有高性能等级的分配器 应用程序(例如 jemalloc ,据我所知是 和单线程应用程序中的普通malloc一样好...... 如果我错了,请纠正我。

  • 在您提出/建议之前,我已经使用WordPress删除了所有内容 可能的内存泄漏。我只需要优化,而不是修复。

  • 内存碎片是一个问题,所以我也应该使用一种方法来优化它。

  • 使用适当的配置指令,用户可以设置 来自服务器的最大可用内存,这就是预分配的原因 我想到了固定内存池。

  • 我没有性能问题;我正在开发这只是为了好玩和好奇。我喜欢学习和尝试新的编程技术。

  • 是的,我使用过callgrind,而malloc是最昂贵的操作之一。

1 个答案:

答案 0 :(得分:2)

由于您说您没有性能问题,因此您无需执行任何操作。把它放在一边。

你需要立足点才能获得任何改善,因为malloc非常快。在几年前的Mac OS X上,我记得约100-200个周期。 (但free也可能需要更多的时间,这应该出现在分析统计数据中。)编写一个更好的通用分配器基本上是不可能的,除了技巧和运气。

但是,特定于您的应用程序的模式仍然可以暴露机会。我已经幸运地获得了与其创建大致相同的顺序释放对象的程序。

  1. 创建一些内存桶。
  2. malloc以线性方式从桶中返回块。
  3. free将块标记为未使用。这可以利用位图,管理的智能指针等。对于纯垃圾收集,不需要显式调用。
  4. 当最后一个存储桶已满时,扫描最近使用过的存储桶,但只检查完全是否为空。
  5. 如果没有空桶,请换一个新桶。
  6. 这是一个可怕的策略,如果有任何碎片,但它可以在普通malloc上提高几个数量级,因为沿着桶扫描直到结束只需1-2循环而不是100-200,并且对于足够小的碎片,你总是可以不经常进行扫描。

    百万分之一的慢速扫描也使许多应用中的这种方法失去了资格。

    我对缓存服务器知之甚少,但这种方法可能适用于高度瞬态的HTTP连接对象。您不需要关注所有malloc,而是需要以最可预测的模式承担最大成本的分配子集。