位置: IT常识 - 正文

推荐一个跨平台内存分配器 feixuwu C++博客(跨平台 gui)

发布时间:2024-01-21
推荐一个跨平台内存分配器 - feixuwu - C++博客推荐一个跨平台内存分配器 昨天一个同事一大早在群里推荐了一个google project上的开源内存分配器(http://code.goog 推荐一个跨平台内存分配器

推荐整理分享推荐一个跨平台内存分配器 feixuwu C++博客(跨平台 gui),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:跨平台rn,推荐一个跨平台的app,跨平台网站,推荐一个跨平台的app,推荐一个跨平台的app,跨平台的好处,跨平台的好处,推荐一个跨平台的软件,内容如对您有帮助,希望把文章链接给更多的朋友!

昨天一个同事一大早在群里推荐了一个google project上的开源内存分配器(http://code.google.com/p/google-perftools/),据说google的很多产品都用到了这个内存分配库,而且经他测试,我们的游戏客户端集成了这个最新内存分配器后,FPS足足提高了将近10帧左右,这可是个了不起的提升,要知道3D组的兄弟忙了几周也没见这么大的性能提升。

如果我们自己本身用的crt提供的内存分配器,这个提升也算不得什么。问题是我们内部系统是有一个小内存管理器的,一般来说小内存分配的算法都大同小异,现成的实现也很多,比如linux内核的slab、SGI STL的分配器、ogre自带的内存分配器,我们自己的内存分配器也和前面列举的实现差不多。让我们来看看这个项目有什么特别的吧。

一、使用方法

打开主页,由于公司网络禁止SVN从外部更新,所以只能下载了打包的源代码。解压后,看到有个doc目录,进去,打开使用文档,发现使用方法极为简单:To use TCMalloc, just link TCMalloc into your application via the "-ltcmalloc" linker flag.再看算法,也没什么特别的,还是和slab以及SGI STL分配器类似的算法。unix环境居然只要链接这个tcmalloc库就可以了!,太方便了,不过我手头没有linux环境,文档上也没提到windows环境怎么使用,打开源代码包,有个vs2003解决方案,打开,随便挑选一个测试项目,查看项目属性,发现仅仅有2点不同:1、链接器命令行里多了 "..\..\release\libtcmalloc_minimal.lib",就是链接的时候依赖了这个内存优化库。2、链接器->输入->强制符号引用 多了 __tcmalloc。这样就可以正确的使用tcmalloc库了,测试了下,测试项目运行OK!

二、如何替换CRT的malloc推荐一个跨平台内存分配器  feixuwu  C++博客(跨平台 gui)

从前面的描述可知,项目强制引用了__tcmalloc, 搜索了测试代码,没发现用到_tcmalloc相关的函数和变量,这个选项应该是为了防止dll被优化掉(因为代码里没有什么地方用到这个dll的符号)。初看起来,链接这个库后,不会影响任何现有代码:我们没有引用这个Lib库的头文件,也没有使用过这个dll的导出函数。那么这个dll是怎么优化应用程序性能的呢?实际调试,果然发现问题了,看看如下代码 void* pData = malloc(100);00401085 6A 64 push 64h 00401087 FF 15 A4 20 40 00 call dword ptr [__imp__malloc (4020A4h)] 跟踪 call malloc这句,step进去,发现是78134D09 E9 D2 37 ED 97 jmp `anonymous namespace'::LibcInfoWithPatchFunctions<8>::Perftools_malloc (100084E0h) 果然,从这里开始,就跳转到libtcmalloc提供的Perftools_malloc了。原来是通过API挂钩来实现无缝替换系统自带的malloc等crt函数的,而且还是通过大家公认的不推荐的改写函数入口指令来实现的,一般只有在游戏外挂和金山词霸之类的软件才会用到这样的挂钩技术,而且金山词霸经常需要更新补丁解决不同系统兼容问题。

三、性能差别原因

如前面所述,tcmalloc确实用了很hacker的办法来实现无缝的替换系统自带的内存分配函数(本人在使用这类技术通常是用来干坏事的。。。),但是这也不足以解释为什么它的效率比我们自己的好那么多。回到tcmalloc 的手册,tcmalloc除了使用常规的小内存管理外,对多线程环境做了特殊处理,这和我原来见到的内存分配器大有不同,一般的内存分配器作者都会偷懒,把多线程问题扔给使用者,大多是加个bool型的模板参数来表示是否是多线程环境,还美其名曰:可定制,末了还得吹嘘下模板的优越性。tcmalloc是怎么做的呢? 答案是每线程一个ThreadCache,大部分操作系统都会支持thread local storage 就是传说中的TLS,这样就可以实现每线程一个分配器了,这样,不同线程分配都是在各自的threadCache里分配的。我们的项目的分配器由于是多线程环境的,所以不管三七二十一,全都加锁了,性能自然就低了。

仅仅是如此,还是不足以将tcmalloc和ptmalloc2分个高下,后者也是每个线程都有threadCache的。关于这个问题,doc里有一段说明,原文贴出来:ptmalloc2 also reduces lock contention by using per-thread arenas but there is a big problem with ptmalloc2's use of per-thread arenas. In ptmalloc2 memory can never move from one arena to another. This can lead to huge amounts of wasted space.大意是这样的:ptmalloc2 也是通过tls来降低线程锁,但是ptmalloc2各个线程的内存是独立的,也就是说,第一个线程申请的内存,释放的时候还是必须放到第一个线程池中(不可移动),这样可能导致大量内存浪费。

四、代码细节1、无缝替换malloc等crt和系统分配函数。

前面提到tcmalloc会无缝的替换掉原有dll中的malloc,这就意味着使用tcmalloc的项目必须是 MD(多线程dll)或者MDd(多线程dll调试)。tcmalloc的dll定义了一个static TCMallocGuard module_enter_exit_hook;的静态变量,这个变量会在dll加载的时候先于DllMain运行,在这个类的构造函数,会运行PatchWindowsFunctions来挂钩所有dll的 malloc、free、new等分配函数,这样就达到了替换功能,除此之外,为了保证系统兼容性,挂钩API的时候还实现了智能分析指令,否则写入第一条Jmp指令的时候可能会破环后续指令的完整性。

2、LibcInfoWithPatchFunctions 和ThreadCache。

LibcInfoWithPatchFunctions模板类包含tcmalloc实现的优化后的malloc等一系列函数。LibcInfoWithPatchFunctions的模板参数在我看来没什么用处,tcmalloc默认可以挂钩最多10个带有malloc导出函数的库(我想肯定是够用了)。ThreadCache在每个线程都会有一个TLS对象:__thread ThreadCache* ThreadCache::threadlocal_heap_。

3、可能的问题

设想下这样一个情景:假如有一个dll 在tcmalloc之前加载,并且在分配了内存(使用crt提供的malloc),那么在加载tcmalloc后,tcmalloc会替换所有的free函数,然后,在某个时刻,在前面的那个dll代码中释放该内存,这岂不是很危险。实际测试发现没有任何问题,关键在这里:span = Static::pageheap()->GetDescriptor(p); if (!span) { // span can be NULL because the pointer passed in is invalid // (not something returned by malloc or friends), or because the // pointer was allocated with some other allocator besides // tcmalloc. The latter can happen if tcmalloc is linked in via // a dynamic library, but is not listed last on the link line. // In that case, libraries after it on the link line will // allocate with libc malloc, but free with tcmalloc's free. (*invalid_free_fn)(ptr); // Decide how to handle the bad free request return; }

tcmalloc会通过span识别这个内存是否自己分配的,如果不是,tcmalloc会调用该dll原始对应函数(这个很重要)释放。这样就解决了这个棘手的问题。

五、其他

其实tcmalloc使用的每个技术点我从前都用过,但是我从来没想过用API挂钩来实现这样一个有趣的内存优化库(即使想过,也是一闪而过就否定了)。从tcmalloc得到灵感,结合常用的外挂技术,可以很轻松的开发一个独立工具:这个工具可以挂载到指定进程进行内存优化,在我看来,这可能可以作为一个外挂辅助工具来优化那些内存优化做的很差导致帧速很低的国产游戏。

本文链接地址:https://www.jiuchutong.com/zhishi/303767.html 转载请保留说明!

上一篇:Hive官方手册翻译(Getting Started) 实践检验真理 51CTO技术博客(hive.)

下一篇:Editorial Calendar为你的WordPress添加编辑日历 让文章定时发布更简单

  • 互联网营销:微博营销的10种操作模式(互联网营销新玩法)

    互联网营销:微博营销的10种操作模式(互联网营销新玩法)

  • 怎么在ppt中加入音频然后自动播放(怎么在ppt中加入动态图片)

    怎么在ppt中加入音频然后自动播放(怎么在ppt中加入动态图片)

  • 华为nova4手机电池容量是多少(华为nova4手机电池容量怎么看)

    华为nova4手机电池容量是多少(华为nova4手机电池容量怎么看)

  • 快手极速版什么时候出来的(快手极速版什么是新用户)

    快手极速版什么时候出来的(快手极速版什么是新用户)

  • 华为mate30快捷键怎么设置(华为mate30快捷键如何重命名)

    华为mate30快捷键怎么设置(华为mate30快捷键如何重命名)

  • 手机为什么电话打不进来(手机为什么电话打不出去也接不了电话)

    手机为什么电话打不进来(手机为什么电话打不出去也接不了电话)

  • word表格属性怎么设置(word表格属性怎么复制)

    word表格属性怎么设置(word表格属性怎么复制)

  • p40的听筒在哪里

    p40的听筒在哪里

  • 摄像头可以录音吗(摄像头可以录音录像吗)

    摄像头可以录音吗(摄像头可以录音录像吗)

  • 手机出现无法连接App Store的情况,排障方法?(手机出现无法连接到相机怎么办)

    手机出现无法连接App Store的情况,排障方法?(手机出现无法连接到相机怎么办)

  • 优化驱动器有什么作用(优化驱动器有害还是有益)

    优化驱动器有什么作用(优化驱动器有害还是有益)

  • 荣耀V20OTG在哪里

    荣耀V20OTG在哪里

  • vivox30网速太慢怎么解决(vivox30网速卡怎么回事)

    vivox30网速太慢怎么解决(vivox30网速卡怎么回事)

  • 华为p40录屏功能在哪设置(华为p40录屏功能怎么能录上声音)

    华为p40录屏功能在哪设置(华为p40录屏功能怎么能录上声音)

  • 视频声音延迟怎么解决(调整视频声音延迟app)

    视频声音延迟怎么解决(调整视频声音延迟app)

  • 微信交电费最晚多久到账(微信交电费最晚到几点)

    微信交电费最晚多久到账(微信交电费最晚到几点)

  • wps怎么调行距

    wps怎么调行距

  • 抖音自动取消关注是怎么回事(抖音自动取消关注软件)

    抖音自动取消关注是怎么回事(抖音自动取消关注软件)

  • 苹果1458是ipad几(ipad 1458是ipad几)

    苹果1458是ipad几(ipad 1458是ipad几)

  • 接入2.4gwifi是什么意思(接入2.4gwi-fi)

    接入2.4gwifi是什么意思(接入2.4gwi-fi)

  • 电脑播放视频没有声音是什么原因(电脑播放视频没有画面是怎么回事)

    电脑播放视频没有声音是什么原因(电脑播放视频没有画面是怎么回事)

  • oppoa5手机显示hd怎么关掉(oppoa5手机显示耳机模式怎么关闭啊)

    oppoa5手机显示hd怎么关掉(oppoa5手机显示耳机模式怎么关闭啊)

  • 如何给文档添加目录(如何给文档添加注释)

    如何给文档添加目录(如何给文档添加注释)

  • 复印机怎么缩印(复印机怎么缩印成a4)

    复印机怎么缩印(复印机怎么缩印成a4)

  • 快手直播竞猜在哪(快手主播竞猜哪里竞猜)

    快手直播竞猜在哪(快手主播竞猜哪里竞猜)

  • 华为mate30用什么系统(华为mate30用什么数据线)

    华为mate30用什么系统(华为mate30用什么数据线)

  • 苹果xs没有电池百分比吗(iphone xs没有显示电池百分比)

    苹果xs没有电池百分比吗(iphone xs没有显示电池百分比)

  • iwatch4可以打电话吗(applewatch4能打电话吗)

    iwatch4可以打电话吗(applewatch4能打电话吗)

  • 荣耀play什么处理器(荣耀play的)

    荣耀play什么处理器(荣耀play的)

  • JEECG微服务架构配置和运行(微服务架构java框架)

    JEECG微服务架构配置和运行(微服务架构java框架)

  • 餐饮发票公司怎么抵税
  • 补缴以前年度增值税和罚款、滞纳金的所得税处理
  • 超率累进税率有哪些税种呢怎么算
  • 入账价值 入账成本 入账金额
  • 卷式发票是什么样的
  • 什么情况下可以要求员工待岗
  • 业务招待费扣除基数的收入包括哪些
  • 会计账簿按外表形式分
  • 普通发票辨别真伪
  • 转让不动产取得的发票
  • 免费的产品
  • 单位员工去外地上班
  • 代收代付如何进行账务处理?
  • 一个公司只有一个财务人员,可以吗
  • 给个人支付劳务报酬怎么做账
  • 注销公司税务一年几次
  • 车辆租赁费用标准
  • 增值税为什么申报不了
  • 年度汇算清缴可以作废吗
  • 稿酬所得的个税计算
  • 增值税税率调整时间16变13
  • 应收账款应计利息公式如何理解
  • 个人所得税生产经营所得
  • 房地产开发企业预收款预缴增值税
  • vue2-elm
  • 修改系统散热方案
  • 已提减值准备的固定资产报废怎么填写
  • chrome谷歌浏览器
  • 固定资产售卖的账务处理
  • 顺流交易合并抵消
  • 小规模纳税人无票收入怎么申报
  • php框架怎么用
  • 收到退回的增值税专用发票账务处理
  • 仓库发货打包以及建议年终总结
  • 注册资本增加了怎么做账
  • 浅谈php设计模式的理解
  • 酒店周转材料怎么摊销
  • 服务费的开票项目是什么
  • 差旅费包括哪些费用
  • 在与sqlserver建立连接时出现
  • 企业所得税汇算表
  • 收据盖发票专用章会被处罚吗
  • 其他应付款付不出去怎么处理好
  • 一般纳税人企业所得税税率多少
  • 增值税期末留抵退税原因采集确认单
  • 递延负债和递延收益
  • 电商刷单返现如何做账务处理合适?
  • 已抵扣的进项税额如何转出
  • 金税盘未响应什么意思
  • 私人借款条怎么写合法
  • 外聘人员差旅费用无票调增
  • 折扣销售方式销售货物只要发票中有注明的折扣额
  • 应收未收的款项如何会计处理
  • 挂靠经营的会计处理是?
  • 税率计税依据
  • 设备基础属于什么基础
  • 数据库中两张表tab1
  • mysql数据库简单介绍
  • 通用SQL存储过程分页以及asp.net后台调用的方法
  • mysql中汉字用什么类型
  • windows性能监视器横坐标
  • macbook launch
  • windows server 2008 r2 iis
  • mac怎么设置图片为桌面
  • linux用中文怎么说
  • win10系统下如何打开internet(ISS)信息服务
  • mac上safari
  • centos7 vncserver
  • shell下同时读取多个文件的方法
  • win10怎么切任务管理
  • win7系统搜索在哪
  • 日历功能在哪里设置
  • windows10运用
  • 电脑迅雷影音在哪个文件夹
  • 提高你工作效率的方法
  • js中ajax完整例子
  • 如何用python写自动化脚本
  • javascript Base类 包含基本的方法
  • 山东省国家税务局总局官网
  • 资源税的税目共有七个其中包括
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号