我目前正在开发一个缓存服务器,它本身就使用了很多RAM(我在具有大量HTTP流量且两个{{3}的服务器上测试它和一个使用它来缓存内存中数据的自定义Web应用程序。
服务器显然执行了大量的malloc / realloc / free操作,这些操作很昂贵,所以我想知道是否应该使用自定义内存分配器,也许是在开始时预先分配一个大“内存池”然后使用它的东西在执行malloc / realloc时提供所请求大小的自由“片段”,并在调用free时将其标记为已释放。
我走的是正确的道路还是不是我真的需要这样的东西?有没有像这样的分配器,还是我必须编写自己的代码?
重要说明:
服务器是单线程(使用多路复用),所以我没有 需要在多线程中具有高性能等级的分配器 应用程序(例如 jemalloc ,据我所知是 和单线程应用程序中的普通malloc一样好...... 如果我错了,请纠正我。
在您提出/建议之前,我已经使用WordPress删除了所有内容 可能的内存泄漏。我只需要优化,而不是修复。
内存碎片是一个问题,所以我也应该使用一种方法来优化它。
使用适当的配置指令,用户可以设置 来自服务器的最大可用内存,这就是预分配的原因 我想到了固定内存池。
我没有性能问题;我正在开发这只是为了好玩和好奇。我喜欢学习和尝试新的编程技术。
是的,我使用过callgrind,而malloc是最昂贵的操作之一。
答案 0 :(得分:2)
由于您说您没有性能问题,因此您无需执行任何操作。把它放在一边。
你需要立足点才能获得任何改善,因为malloc
非常快。在几年前的Mac OS X上,我记得约100-200个周期。 (但free
也可能需要更多的时间,这应该出现在分析统计数据中。)编写一个更好的通用分配器基本上是不可能的,除了技巧和运气。
但是,特定于您的应用程序的模式仍然可以暴露机会。我已经幸运地获得了与其创建大致相同的顺序释放对象的程序。
malloc
以线性方式从桶中返回块。free
将块标记为未使用。这可以利用位图,管理的智能指针等。对于纯垃圾收集,不需要显式调用。这是一个可怕的策略,如果有任何碎片,但它可以在普通malloc
上提高几个数量级,因为沿着桶扫描直到结束只需1-2循环而不是100-200,并且对于足够小的碎片,你总是可以不经常进行扫描。
百万分之一的慢速扫描也使许多应用中的这种方法失去了资格。
我对缓存服务器知之甚少,但这种方法可能适用于高度瞬态的HTTP连接对象。您不需要关注所有malloc
,而是需要以最可预测的模式承担最大成本的分配子集。