Malloc技术原理解析以及在转转搜索业务上的实践( 八 )


4.4 部分参数解析部分主流的tcmalloc配置参数有:

  • TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES: 限制每个线程本地缓存的最大总大小;
  • TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD: 内存最大分配阈值;
  • TCMALLOC_SAMPLE_PARAMETER : 采样时间间隔;
  • TCMALLOC_RELEASE_RATE:用于控制tcmalloc内部的内存回收速率 。
4.5 特性分析
  • 高性能:TCMalloc在内存分配和释放过程中 , 大多数情况下都能够避免产生过多的竞争 。这是因为它维护了线程本地缓存(thread-cache) , 以满足当前线程的内存分配需求 。这意味着在许多情况下 , 应用程序的内存申请不会涉及到锁的竞争 , 尤其是在多核处理器的环境下 , TCMalloc表现出色 , 并具有良好的可扩展性;
  • 智能内存资源管理:TCMalloc能够灵活地管理内存资源 , 当用户不再需要内存时 , TCMalloc会智能地选择是重新利用这些内存还是将其归还给操作系统 , 以便更有效地利用系统资源;
  • 降低内存开销:通过以页面(page)为单位进行内存分配 , TCMalloc降低了每个请求的内存开销 。这种优化在处理小对象时特别有效 , 有效地减少了内存浪费;
  • 低开销的内部信息统计:TCMalloc具有低开销的内存使用信息统计功能 , 可以以细粒度的方式跟踪应用程序的内存占用情况 。这有助于用户更详细地了解TCMalloc内部的内存使用情况 , 从而更好地进行性能调优和资源管理 。
5 实践5.1 背景当前转转的服务中 , 很多都存在堆外内存较高的现象 。以转转搜索排序服务为例 , 目前线上服务jvm堆内存上限为18G , 服务内无堆外的特征缓存等数据 , 堆外内存的大小超出预期 , 很多物理机的内存已经开始告急 , 初步判断原因为相关的服务中用到了tensorflow进行推断 , linux默认使用的glibc的malloc实现在内存池资源回收上存在缺陷 , 导致申请过的内存无法还给操作系统 , 上文的梳理和特性分析体现出主流的两种非原生malloc:tcmalloc和jemalloc都可能会改善这一状况 , 因此下面对三种不同的malloc进行实践分析 。
5.2 准备工作1.安装jemalloc和tcmalloc:
  • tcmalloc:需要提前安装libunwind和gperftools(自带tcmalloc)并配置环境变量生效 , 下文中的实验采用的是gperftools2.10和centos7;
  • jemalloc:下载最新版本的jemalloc , 编译安装并配置环境变量即可 , 下文中的实验采用的是jemalloc5版本 。
2.在服务启动时 , 终端设置export LD_PRELOAD={对应malloc.so文件的路径}和export MALLOC_CONF={指定的malloc参数}后 , 重新终端启动服务即可生效 。其中jemalloc经过多次尝试 , 选择了利用MALLOC_CONF配置参数:background_thread:true , metadata_thp:auto , dirty_decay_ms:30000 , muzzy_decay_ms:30000来获得最佳的表现(其含义见下表) , 而tcmalloc和ptmalloc经过测试 , 默认的参数表现最佳 , 3个malloc的最佳参数的测试过程同样是采用压测+线上对比来进行的 , 较为繁琐所以不再赘述 。
参数
含义
narenas
默认为ncpus的四倍 , 用于设置线程独占的 arena数量 。
dirty_decay_ms与muzzy_decay_ms
控制内存页的过期时间 。jemalloc使用一种延迟回收策略 , 根据指定的时间段将内存页从"dirty"状态(已经写入)转换为"muzzy"状态(未写入) , 然后再回收
background_thread
启用后台线程 。jemalloc支持后台线程来定期处理内存释放操作 , 这可以降低内存碎片并提高性能 。启用此参数后 , jemalloc将自动创建和管理后台线程 。
tcache
禁用tcache(thread-local cache) 。tcache是jemalloc的一项特性 , 用于线程本地的内存分配缓存 。通过禁用它 , 您可以在一定程度上减少jemalloc的线程局部性 , 适用于高并发场景或者特定需求下 。


推荐阅读