其他
干货 | 提升内存管理效率,携程酒店查询服务轻量化探索和实践
作者简介
NekoMatryoshka,携程酒店资深后端开发工程师,主要工作是缓存类组件的开发维护,并对业务应用的排障和优化有所关注。
减少内存增长速度:压缩本地缓存,减少浮动内存的产生,并对线程,类库,参数和代码逻辑进行针对性的优化和调整。 提升内存管理效率:加强JVM等服务依赖的基础组件其本身的性能。
官方类库缺失:JDK11中移除了一系列官方类库,其中部分类库只是从rt.jar中被拆分,可以简单的通过maven补回,例如javax.*,但是其他一些包含危险操作的类库则被直接删除,例如jdk.nashorn,sun.misc等,一般也可以通过重写来绕过这些代码。
权限控制:JDK11中对各种权限做了更精细的控制。例如自代理需要使用参数`-Djdk.attach.allowAttachSelf`控制,而跨类库的反射权限则需要用`--add-exports=`和`--add-exports`来打开。如果未能注意到这些参数则会造成大量权限控制报错。
第三方类库报错:此类报错一般都是兼容性问题导致,Lombok和AspectJ等类库需要根据JDK版本来选择对应的类库版本。主要排查难点在于报错的形式五花八门,报错信息对定位几乎没有帮助,有时候很难确定是哪个类库导致的。
减少申请和释放操作的时间和开销 减少小对象分配带来的内存碎片 减少分配器本身数据结构的额外内存开销
arena(分配区)是ptmalloc中的内存缓冲区,在一个环形链表上被管理。也是ptmalloc中最小的锁颗粒度。
bin(空闲链表)是arena中用于管理可用内存块的链表。不同的bins根据其管理的内存块大小而被分为fast、unsorted、small和large四种。
chunk(内存块)则是用户申请和释放内存的最小单位。bins的头部永远是一个被称为top chunk的空闲块,当没有合适的chunk时,会扩容并返回top chunk来处理请求。
内存池(减少频繁的系统调用和内存碎片):用户free掉的内存,不会被直接被归还给系统,而是暂存到bins中,供下次申请时直接分配。
多分配区(减少锁竞争):所有内存操作都需要加锁,如果没有找到未上锁的arena,则会新增一个副arena并上锁,直到arena的数量上限。
额外内存开销大:每个chunk都需要额外消耗8b的内存,而chunk是内存操作的最小单位,这会导致整体上浪费了非常多内存。
内存利用率不稳定:由于多分配区的机制,激烈的锁竞争会导致副arena数量快速增多。并且,新增的副arena永远不会被销毁,且保留会其初始的chunk。这意味着在一台16核的标准机器上最多会有128个arena,并占用高达8G的堆外缓冲区。
多线程性能差:所有的内存操作都需要进行悲观锁的加锁解锁操作,导致其性能较差。同时,即使有多分配区机制,在动辄500个以上线程的生产环境中这个并发量完全不够。
回收机制简陋:由于bins是链表结构,ptmalloc的内存收缩必须从上向下收缩,这意味着只要后申请的内存没有被释放,之前申请的所有chunk都无法被收缩,这导致了在管理长周期内存时,有内存泄漏的可能性。
前置条件:由于轻量化的需要,应用目前仅仅能给堆外大约2.5G的空间。并且G1本身使用的堆外空间是CMS的4-6倍之多。而原来的32G的堆外空间充足,所以之前没有发现类似问题。
由于大量的缓存、快照和报文的处理,应用本身有非常频繁和重量级的NIO和序列化/压缩操作(尤其是点火的时候,线程数非常多),这导致了应用会高频的申请和释放堆外内存作为IO缓冲区。因此ptmalloc在这种情况下新增了大量的arena来避免频繁的锁竞争(下图中有大量64M大小的内存块)。
ptmalloc本身的释放机制就导致申请的内存被归还的特别慢,甚至有内存溢出的倾向,这些因素综合在一起引起了OOM的发生。
从运维方面来看,集群为了方便调度,一般会限制几个预设的容器配置以供选择。在资源相对紧张的情况下,jemalloc可以使得应用整体的部署更加灵活,而使用默认的ptmalloc则会被迫将容器配置向上升级,否则就需要额外对特殊配置进行审批和调度,这样不但会造成不必要的资源浪费,同时在流量尖峰时也难以对集群进行调度和扩容。
在成本方面,从测试结果出发,仅仅使用jemalloc本身就能比ptmalloc在每台机器上节省1-1.5G的堆外内存,虽然在单机上可能不够显著,但是推广到整个云的范围时收益应该是非常可观的。
性能上,jemalloc的内存回收和多线程机制更加高效和智能化,对低配置机器更加友好,能大大加强内存资源紧张的机器上服务的鲁班性,同时对IO、GC、类加载等多线程native操作有较大的优化。
从迁移角度看,迁移到jemalloc几乎是无成本的操作,仅仅需要简单的镜像自定义和一定的灰度测试,就可以完成优化。
“携程技术”公众号
分享,交流,成长