首页 > ATS插件开发中内存泄露问题的解决方法探讨

ATS插件开发中内存泄露问题的解决方法探讨

接触ATS开发已经有几年了,开发过内核的模块,也从事过插件的开发.内存泄露问题一直是一个困扰大多数ATS开发者的头疼的问题,下面说说我自己的感受和思考.这里这关注ATS插件开发这个话题.源码的example和plugins目录分别给出了不同业务场景的插件实例,很多都对我们有很大地启发,但是其中也存在一些问题,特别是缓存泄露的问题,在example给出的示例插件中比较常见.

1.http头中的mime field处理的内存泄露风险

ATS插件主要是在每一个http transaction交互中的指定阶段添加HooK API,俗称"钩子".比如在下面的钩子中

为此我们为了业务逻辑的需要,免不了要处理http request header和http response header中的各种host,url,status code,mime field,比如获取,修改,增加,删除等操作,按照example中的源码, 对各种异常处理不很全面, 在生产环境中运行中会内存泄露的风险. 

对这种风险的一个解决方法就是大量使用do{...}while(0),请看下面的两段代码的示例



由上可见, do{...}while(0)很多地解决了异常情况退出函数的资源释放问题,较大减少了重复的程序语句,是代码更robust,更简洁.





2.自己引入外部库时创建释放内存可能导致的内存泄露风险

我曾经在插件中想引入TSIOBuffer一类的内存池管理容器来避免直接调用TSmallac()和TSfree()来频繁释放内存,但是经过细心地调研代码,我发现TSIOBuffer提供的接口只供4096以内的小内存进行char*读出转换的处理,对一个大小为300K左右的html页面来说,使用TSIOBuffer一类的内存池管理并不恰当.我也研究了nginx的memory pool的涉及思想,发现内存池管理同样还是针对4096以内的小内存进行的.对大的内存,ATS和Nginx内部还是直接调用malloc和free来直接分配和释放的.

这样就存在一个风险, 这么大的内存,如果在异常情况下,没有释放,将会导致内存泄露的巨大风险,如何解决这个问题?

举例来说,我想对着指定规则的某几类的url的html进行正则匹配, 更改一下它内部的html代码,比如改个js的链接地址,我不可避免地需要经历如下步骤:

从upstream获取html完整内容==>解压缩=>pcre正则查找并替换=>压缩=>更新Content-Length头域=>写入downstream



在这个过程中,解压加压缩,pcre查找替换都要涉及分配较大的内存,如果在这个流程中的某一步出现异常,没有释放之前分配的内存就很危险.我对此探索出一个使用http transaction内部进行内存管理的方法,就是创建一个内存管理单链表,将这个流程中需要动态分配的所有内存都挂接在这个单链表山个,待要退出流程时,就一次性释放该单链表上动态分配的所有内存,这种方法较好地解决了自身申请释放内存的问题.

下面是插件内存调试图



更多相关:

  • 更多内容,欢迎关注微信公众号:全菜工程师小辉~前言在笔者上一篇博客,详解了NIO,并总结NIO相比BIO的效率要高的三个原因,彻底搞懂NIO效率高的原理。这篇博客将针对第三个原因,进行更详细的讲解。首先澄清,零拷贝与内存直接映射并不是Java中独有的概念,并且这两个技术并不是等价的。零拷贝零拷贝是指避免在用户态(User-space)...

  • 一、预备知识—程序的内存分配  一个由c/C++编译的程序占用的内存分为以下几个部分  1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,如果还不清楚,那么就把它想成数组,它的内存分配是连续分配的,即,所分配的内存是在一块连续的内存区域内.当我们声明变量时,那么编译器...

  • 我的爱机是一台ThinkPad T420,原装三星DDR 1333 4G内存一根,还剩一根内存位置,最近趁京东6.18促销,准备增加一根物理内存。为了确保兼容性,觉得仍然选购DDR 1333 4G内存,于是购买了金士顿这款,比如DDR3 1600的还贵。 这个安装过程完全参照该内存的网页提示进行 这里简单记录一下,以备...

  • 陪伴我多年的老本ThinkPad T420渐渐垂垂老矣, 我想更新一下可以更新的部分, 比如将2.5寸HDD更换为SSD, 将单条4G内存再增加一根, 凡此种种想法, 可能最后归结为如何获取该笔记本的硬件配置信息, 在windows下面使用鲁大师之类的检测软件, 也许很好搞定,但是在Ubuntu 14.04平台上如果办到呢? 很简单...

  • 一.内存错误出现的场景 这几天在重构ATS插件代码的过程中遇到了烦人的内存泄露问题, 周五周六连续两天通过走查代码的方法,未能看出明显的导致内存错误的代码, 同时也觉得C和C++混合编程得到一个动态库, 在一个.cpp主文件中,即用new又用malloc来动态分配内存, 可能会导致内存错误.后来网上调研和查资料发现, new和mal...

  • 这是学习笔记的第 2103 篇文章 最近碰到了一个奇怪的权限问题,问题的背景是业务同学反馈在下班后,有一个数据表出现了阻塞,导致后续的业务流程都产生了拥堵,在对这个问题进行分析发现,业务同学所谓的拥堵,阻塞是数据库连接出了问题。当然我们进行了一些深入的沟通,对整个问题的情况有了一个更为清晰的了解。    6:30左右,业务同学发现...

  • 今天我将为大家介绍逻辑回归的含义并展示Pytorch实现逻辑回归的方法,先我们来看看一个问题。问题: 大家想必对MNIST数据集已经非常熟悉了吧?这个数据集被反复“咀嚼”,反复研究。今天我们将换个角度研究MNIST数据集。假设现在不使用卷积神经网络,又该使用什么方法来解决MNIST分类问题呢?一、观察数据 在开始分析数据问题之前,我...

  • 写在前面 最近公众号的活动让更多的人加入交流群,尝试提问更多的我问题,群主也在积极的招募更多的小伙伴与我一起分享,能够相互促进。 这里总结群友经常问,经常提的两个问题,并给出我的回答: (1)啥时候能出教程,能够讲解PCL中的各种功能? (2)如何解决大规模点云的问题呢?   以下给出正式的解答以及计划安排 问题1:对于...

  •   我刚刚开始接触PCL,懂的东西也很少,所以总是出现各种各样的问题,每次遇见问题的时候要查找各种各样的资料,很费时间。所以,今天我把我遇见的常见问题分享给大家,讲解的步骤尽量详细,让和我一样基础差的小伙伴能尽快进入到PCL点云库的学习中,希望能和大家进步。 运行环境:PCL-1.8.0-AllInOne-msvc2013-win...

  • 这篇博文中主要收集我开发过程中遇到的Makefile相关的问题, 以免自己日后再犯类似的错误. 今天就遇到一个很弱的问题, Makefile显示如下错误: 出现该问题是因为我写错了标注处的代码: $和()之间有空格了, 这里必须是$(), 不能有空格的...