• 尝试在Mac/iOS上使用tcmalloc库


    概述

           TCMalloc 是 Google 开发的内存分配器,在不少项目中都有使用,例如在 Golang 中就使用了类似的算法进行内存分配。它具有现代化内存分配器的基本特征:对抗内存碎片、在多核处理器能够 scale。据称,它的内存分配速度是 glibc2.3(glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现)中实现的 malloc的数倍。

      TCMalloc全称Thread-Caching Malloc,即线程缓存的malloc,实现了高效的多线程内存管理,用于替代系统的内存分配相关的函数(malloc、free,new,new[]等)。

      TCMalloc是gperftools的一部分,除TCMalloc外,gperftools还包括heap-checker、heap-profiler和cpu-profiler。本文只讨论gperftools的TCMalloc部分。

      git仓库:https://github.com/gperftools/gperftools.git

      官方介绍:https://gperftools.github.io/gperftools/TCMalloc.html

    安装

           从git仓库clone版本的gperftools的安装依赖autoconf、automake、libtool,以Mac为例:

      $ brew install autoconf automake libtool

      Autoconf实际上是一个工具集,其中包含aclocal、autoheader和autoconf等可执行文件。Libtool软件包是第三个重要的GNU工具,它的作用是确定共享库在特定平台上的特性。

      $ ./autogen.sh

      生成Makefile

      $ ./configure

      编译

      $ make

      安装

      $ make install

      默认安装在/usr/local/下的相关路径(bin、lib、share),可在configure时以--prefix=PATH指定其他路径。

           TCMalloc是如何生效的

      为什么指定-ltcmalloc或者与libtcmalloc_and_profiler.a连接之后,对malloc、free、new、delete等的调用就由默认的libc中的函数调用变为TCMalloc中相应的函数调用了呢?答案在libc_override.h中

      Qt工程中使用tcmalloc,新建工程qtTCmallocTest,pro文件中链接静态库libtcmalloc.a或者动态库libtcmalloc.dylib,我使用Mac平台的clang构建正常,运行也正常,Demo运行截图如下图所示,一切都好!

      

      我使用iOS Simulator构建出现警告错误:

      :-1: warning: URGENT:building for iOS Simulator simulator, but linking against dylib (/usr/local/lib/libtcmalloc.dylib) built for macOS. Note: This will be an error in the future.

           实际运行也会有运行时的类似提示导致最终无法在iOS模拟器上运行:

       

      解决办法:重新编译配置

           $make uninstall                          // 删除/usr/local/lib下的tcmalloc库

           $make clean                              // 清除make产生的临时文件

           // 重新configure来配置,只生成minimal的静态库(.a)

           $./configure --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --enable-minimal --enable-static --disable-shared

           $make & make install

           编译安装成后后

           $cd /usr/local/lib

           $ls

          

           可见只生成了libtcmalloc_minimal.a和libtcmalloc_minimal_debug.a

           查看静态库的架构:

           $lipo –info libtcmalloc_minimal.a

          

           可见是x86_64架构的静态库,我们的iOS模拟器是64位处理器,测试需要x86_64架构库,看起来可以使用的。

      现在重新在Qt Creator中使用iOS Simulator构建我们上面的qtTCmallocTest Demo,在pro文件中添加静态库libtcmalloc_minimal.a,编译链接,结果成功构建,运行时却出错了~

      

      错误提示在tcmalloc的源码中,尝试free了已经失效的指针导致出错。可能的原因是程序启动后会调用glibc内存分配的malloc、free等函数,而tcmalloc库就已经将glibc中的内存分配替换成了自己的,此时有点过早调用导致出错。

      解决:注释修改tcmalloc源码相关部分,然后再重新make以及make install

      找到libc_override_osx.h,注释部分代码

      

       

      重新make过程中还会出现如下错误:

      

      可以看到是cfree和pvalloc引用错误,找到tcmalloc_unittest.cc可以看到如下代码:

           #if defined(_WIN32)

      # define cfree free         // don't bother to try to test these obsolete fns

      # define valloc malloc

      # define pvalloc malloc

      将该文件中用到cfree的地方用free替代,用到valloc和pvalloc的地方用malloc替代,保存后,再重新make,没啥错误,紧接着make install。

      再次构建Demo,并运行:

      

      注意:手机等嵌入式内存等较小,程序中不宜不断申请内存,可能造成内存不够用导致程序崩溃退出。

      到此为止,使用tcmalloc静态库尝试可以在iOS模拟器上运行了~

      但是我在iOS真机上编译时却提示找不到arm64架构符号的错误:

      

      可见在Mac OS的终端中执行的./configure & make & make install等操作编译出来的静态库和动态库是针对Mac平台的,iOS平台不兼容导致无法使用。

      该文章指出:iOS用不了谷歌的tcmalloc,无语了~

      Compile tcmalloc for iOS,but getting errors进行了Compile tcmalloc for iOS的尝试,但是遇到了错误,看底下评论,这一部分在官网文档中并没有涉及,也希望借此机会来完善tcmalloc对iOS的支持。

      我努力尝试Clang交叉编译iOS真机版本的tcmalloc,最终没有编译出可以正常使用的arm64架构的静态库,目前是个难题,烦请哪位大神给予指导!

  • 相关阅读:
    Servlet监听器及在线用户
    数据分页jdbc+mysql实现
    使用ajax验证用户名重复
    Mysql中的事务
    用户登录注册案例分析
    Java连接mysql数据库
    Java连接sqlite数据库
    虚拟主机TOMCAT配置
    用jquery控制表格奇偶行及活动行颜色
    JDK安装后 没有tools.jar 和dt.jar包的解决办法
  • 原文地址:https://www.cnblogs.com/MakeView660/p/11491505.html
Copyright © 2020-2023  润新知