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中的源碼, 對各種異常處理不很全面, 在生產環境中運行中會內存泄露的風險.?
2.自己引入外部庫時創建釋放內存可能導致的內存泄露風險
我曾經在插件中想引入TSIOBuffer一類的內存池管理容器來避免直接調用TSmallac()和TSfree()來頻繁釋放內存,但是經過細心地調研代碼,我發現TSIOBuffer提供的接口只供4096以內的小內存進行char*讀出轉換的處理,對一個大小為300K左右的html頁面來說,使用TSIOBuffer一類的內存池管理并不恰當.我也研究了nginx的memory pool的涉及思想,發現內存池管理同樣還是針對4096以內的小內存進行的.對大的內存,ATS和Nginx內部還是直接調用malloc和free來直接分配和釋放的.
這樣就存在一個風險, 這么大的內存,如果在異常情況下,沒有釋放,將會導致內存泄露的巨大風險,如何解決這個問題?
舉例來說,我想對著指定規則的某幾類的url的html進行正則匹配, 更改一下它內部的html代碼,比如改個js的鏈接地址,我不可避免地需要經歷如下步驟:
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),請看下面的兩段代碼的示例
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
下面是插件內存調試圖
總結
以上是生活随笔為你收集整理的ATS插件开发中内存泄露问题的解决方法探讨的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ATS插件中配置文件自动更新思路
- 下一篇: 在Ubuntu 14.04 64bit下