memory-management - 强制 malloc 预故障/MAP_POPULATE/MADV_WILLNEED 整个程序/进程的所有分配
问题描述
为了进行一些用户空间性能分析,我想将分配内存的成本与访问它的操作完全分开。应用程序不会过度分配,因此每个被映射的页面都会出错,可能在分配后不久运行的代码中。
我想做的是设置一些标志、环境变量等,告诉malloc
它应该统一地做相当于调用mmap(..., MAP_POPULATE)
或madvise(..., MADV_WILLNEED)
或只是触摸它分配给自己的任何页面的每一页。在任何平台(!)上,我都没有找到任何描述执行此操作的方法的文档。是否存在一些完全没有记录的现有技术,取决于我的搜索能力?这是从根本上被误导还是坏主意?
如果我想自己实现这个,我正在考虑一个LD_PRELOAD
只包括malloc
调用底层的重新实现,malloc
然后做这madvise
件事(至少对大页面行为有点不可知)。任何不应该工作的理由?
解决方案
malloc
是最常用但相对较慢的常用功能之一。因此,多年来它受到了很多优化关注。我严重怀疑任何认真的实现malloc
都会像在每次调用时检查环境变量所需的字符串解析那样慢。
LD_PRELOAD
这不是一个坏主意,考虑到你在做什么,你甚至不需要重新编译来在配置文件和发布版本之间切换。如果你愿意重新编译,我建议你做一个#define malloc(size) { malloc(size); mmap(...);}
. 您甚至可以在编译命令行中执行此操作-Dmalloc=...
(只要系统 malloc 本身不是一个定义,它会覆盖 cli )。
另一种选择是查找/实现一个程序,该程序使用调试接口来拦截和重定向对malloc
. 理论上,您可以通过弄乱后编译(或后加载)程序的导入部分来指向您的 dll/so 文件来做到这一点。
编辑:再想一想,定义可能不适用于每个分配,因为它通常由编译器暗示(例如new
)。
推荐阅读
- sql - 如何为所有表编写 PL/SQL 包
- javascript - 反应采取错误验证的多步骤形式
- c++ - QT:管理来自 QNetworkReply 的回复
- springdoc - 如何在 Spring Boot 和 Spring doc 中隐藏基于 Profiles 的端点?
- xcode - SwiftUI: Problem with 3DEffect in a ScrollView
- php - 作曲家需要在 laravel 中显示错误
- rust - 如何解决闭包中的生命周期冲突?
- shopware - 适用于 Doofinder 插件的 Shopware 产品导出提要
- node.js - 使用 PassportJS 进行管理员登录
- kubernetes - Kubernetes pod DNS 解析