日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Protobuf使用不當導致的程序內(nèi)存上漲問題-創(chuàng)新互聯(lián)

protocol buffers[1]是google提供的一種將結(jié)構化數(shù)據(jù)進行序列化和反序列化的方法,其優(yōu)點是語言中立,平臺中立,可擴展性好,目前在google內(nèi)部大量用于數(shù)據(jù)存儲,通訊協(xié)議等方面。PB在功能上類似XML,但是序列化后的數(shù)據(jù)更小,解析更快,使用上更簡單。用戶只要按照proto語法在.proto文件中定義好數(shù)據(jù)的結(jié)構,就可以使用PB提供的工具(protoc)自動生成處理數(shù)據(jù)的代碼,使用這些代碼就能在程序中方便的通過各種數(shù)據(jù)流讀寫數(shù)據(jù)。PB目前支持Java, C++和Python3種語言。另外,PB還提供了很好的向后兼容,即舊版本的程序可以正常處理新版本的數(shù)據(jù),新版本的程序也能正常處理舊版本的數(shù)據(jù)。

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務,包含不限于成都網(wǎng)站制作、做網(wǎng)站、路橋網(wǎng)絡推廣、微信小程序定制開發(fā)、路橋網(wǎng)絡營銷、路橋企業(yè)策劃、路橋品牌公關、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務,您的肯定,是我們大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學生創(chuàng)業(yè)者提供路橋建站搭建服務,24小時服務熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

筆者在項目的測試過程中,遇到了一個protocal buffer使用不當?shù)故堑哪K內(nèi)存不斷上漲的問題。這里和大家分享一下問題的定位、分析以及解決過程。

1.   問題現(xiàn)象

5月,出現(xiàn)問題的模塊(以下成為模塊)內(nèi)存有泄露的嫌疑,表現(xiàn)為程序在啟動后內(nèi)存一直在緩慢的上漲。由于該模塊每天都存在重啟的操作,因此沒有帶來較大的影響。

8月,發(fā)現(xiàn)線上模塊的內(nèi)存上漲速度加快。

9月,模塊線上出現(xiàn)內(nèi)存報警。內(nèi)存使用量從啟動時的40G,在70小時左右上漲到50G,由于會出現(xiàn)OOM的風險,模塊不得不頻繁重啟。

9月底,模塊的某個版本上線后,由于內(nèi)存使用量稍有增加,導致程序在啟動后不到24小時內(nèi)就出現(xiàn)內(nèi)存報警,線上程序的穩(wěn)定受到非常大的影響。線上程序回滾,并且停止該模塊的所有功能迭代,直到內(nèi)存問題解決為止。

模塊是整個系統(tǒng)最核心的模塊,業(yè)務的停止迭代對產(chǎn)品的研發(fā)效率影響巨大。問題亟需解決!

2.   問題復現(xiàn)

出現(xiàn)這種問題后,首先要做的就是在線下復現(xiàn)問題,這樣才能更好的定位問題,并且能夠快速的驗證問題修復的效果。但是經(jīng)過多天的嘗試,在QA的測試環(huán)境中,模塊的內(nèi)存表現(xiàn)情況均與線上不一致。具體表現(xiàn)為:

1)線上模塊的內(nèi)存一直在上漲,直到機器內(nèi)存耗盡,模塊重啟;線下模塊的內(nèi)存在壓力持續(xù)若干小時后就趨于穩(wěn)定,不再上漲。

2)線下環(huán)境中,模塊的內(nèi)存上漲速度沒有線上快。

出現(xiàn)這兩種情況的原因后面再解釋。線上線下表現(xiàn)的不一致給問題的復現(xiàn)和效果驗證帶來了一定的困難。但好在在線下環(huán)境中內(nèi)存使用量依然是上漲的,可以用來定位問題。

3.   模塊定位

小版本間升級點排查。對于這個內(nèi)存上漲已存在數(shù)月的模塊來說,要直接定位問題的難度是非常大的,而且投入會十分巨大。為了使模塊的功能迭代盡快開始,最初我們將定位的焦點聚焦于近期模塊上線的功能排查。寄希望于通過排查這些數(shù)量較少的升級,發(fā)現(xiàn)對內(nèi)存的影響。經(jīng)過2天的排查,沒有任何的發(fā)現(xiàn)。

結(jié)合該模塊內(nèi)存的歷史表現(xiàn)和近期升級功能的排查結(jié)果,我們認為模塊的內(nèi)存增長很可能不是泄露,而是某些數(shù)據(jù)在不斷的調(diào)用過程中不斷的增大,從而導致內(nèi)存不斷的上漲。理論上,經(jīng)過足夠長的時間后程序的內(nèi)存使用是可以穩(wěn)定的。但是受限于程序的物理內(nèi)存,我們無法觀察到內(nèi)存穩(wěn)定的那一刻。

排除數(shù)據(jù)熱加載導致的內(nèi)存泄露。在線下環(huán)境中,所有的數(shù)據(jù)文件都沒有更新,因此排除了數(shù)據(jù)熱加載導致的內(nèi)存泄露。

      各模塊逐步排查。小版本間的升級點排查無果后,我們將排查的方法調(diào)整為對程序內(nèi)的各個子模塊(簡稱module)逐個排除的方法。模塊的module共有13個,如果逐個查,那么消耗的時間會特別多。在實施的過程中采用了二分法進行分析。具體的是某個module為中間點,將該module及以后的模塊去掉,來觀察模塊的內(nèi)存變化情況。在去掉中間module(含)之后的模塊后,發(fā)現(xiàn)內(nèi)存的上漲速度下降了30%,說明該module之前的模塊存在70%的泄露。通過分析這些模塊,發(fā)現(xiàn)某個module (簡稱module A) 的嫌疑大。

通過UT驗證內(nèi)存上漲情況。在之前確定主要泄露module的過程中,我們采用在真實環(huán)境中進行驗證的方法。這個方法的缺點是時間消耗巨大。啟動程序,觀察都需要消耗很長的時間,一天只能驗證一個版本。為了加快問題的驗證速度,并結(jié)合模塊的特點,我們采用了寫UT調(diào)用module的方法進行驗證。每次驗證的時間只需要30分鐘,使得問題驗證速度大大加快。

部署監(jiān)控,定位問題。通過寫UT,我們排除了module A中的兩個子module。并且,我們發(fā)現(xiàn)module A單線程的內(nèi)存上漲速度占線上單線程上漲量的30%,這個地方很可能存在著嚴重的問題。在UT中,我們對這個module中最主要的數(shù)據(jù)結(jié)構merged_data(存儲其包含的子module的特征數(shù)據(jù))進行了監(jiān)控。我們發(fā)現(xiàn),merged_data這個數(shù)據(jù)結(jié)構的內(nèi)存一直上漲,上漲量與module A整體的量一致。到此,我們確認了merged_data這種類型的結(jié)構存在內(nèi)存上漲。而這種類型的數(shù)據(jù)結(jié)構在模塊中還有很多,我們合理的懷疑整個模塊的內(nèi)存上漲都是這種情況導致的。

4.   問題分析

我們先看下module A中merged_data字段的用法。其主要的使用過程如下:

 Protobuf使用不當導致的程序內(nèi)存上漲問題

通過上面的代碼,我們可以看到_merged_data字段,在run函數(shù)中會向里面插入數(shù)據(jù),在reset函數(shù)中會調(diào)用Clear方法對數(shù)據(jù)進行清理。結(jié)果監(jiān)控中發(fā)現(xiàn)的_merged_data占用的內(nèi)存空間不斷的變大。通過查閱protobuf clear函數(shù)的介紹,我們發(fā)現(xiàn):protobuf的message在執(zhí)行clear操作時,是不會對其用到的空間進行回收的,只會對數(shù)據(jù)進行清理。這就導致線程占用的數(shù)據(jù)越來越大,直到出現(xiàn)理論上的大數(shù)據(jù)后,其內(nèi)存使用量才會保持穩(wěn)定。

我們可以得到這樣一個結(jié)論:protobuf的clear操作適合于清理那些數(shù)據(jù)量變化不大的數(shù)據(jù),對于大小變化較大的數(shù)據(jù)是不適合的,需要定期(或每次)進行delete操作。

圖1反映出模塊中一些主要protobuf message的變化情況。baseline-old是程序啟動后的內(nèi)存情況。baseline-new是程序啟動6小時后的內(nèi)存情況,可以看到所有的數(shù)據(jù)結(jié)構內(nèi)存占用量都有增加。并且大部分的數(shù)據(jù)都有大幅的增加。

Protobuf使用不當導致的程序內(nèi)存上漲問題

5.   問題解決

在了解了問題的原因后,解決方案就比較簡單了。代碼如下:

Protobuf使用不當導致的程序內(nèi)存上漲問題

優(yōu)化的代碼中,在每次reset的時候,都會調(diào)用scoped_ptr的reset操作,reset會delete指針指向的對象,然后用新的地址進行賦值。優(yōu)化后的效果如圖2所示。newversion-old是優(yōu)化版本啟動1小時候的數(shù)據(jù),newversion-latest是優(yōu)化版本啟動6小時后的數(shù)據(jù)。可以看到從絕對值和上漲量上,優(yōu)化效果都非常明顯。

Protobuf使用不當導致的程序內(nèi)存上漲問題

這個優(yōu)化方法可能存在一個問題:那就是每次進行reset時,都會對數(shù)據(jù)進行析構,并重新申請內(nèi)存,這個操作理論上是非常耗時的。內(nèi)存優(yōu)化后,可能會導致程序的CPU消耗增加。具體CPU的變化情況還需要在測試環(huán)境中驗證。

6.   問題驗證

優(yōu)化版本的表現(xiàn)情況如圖3。

Protobuf使用不當導致的程序內(nèi)存上漲問題

Protobuf使用不當導致的程序內(nèi)存上漲問題

圖4顯示的是優(yōu)化版本與基線版本的CPU IDLE對比情況??梢钥吹絻?yōu)化版本的CPU IDLE反而更高,CPU占用變少了。一個合理的解釋是:當protobuf的messge數(shù)據(jù)量非常大時,其clear操作消耗的CPU比小message的析構和構造消耗的總的CPU還要多。

下面是Clear操作的代碼。

Protobuf使用不當導致的程序內(nèi)存上漲問題

Protobuf使用不當導致的程序內(nèi)存上漲問題

Protobuf使用不當導致的程序內(nèi)存上漲問題

Protobuf使用不當導致的程序內(nèi)存上漲問題

Protobuf使用不當導致的程序內(nèi)存上漲問題

Protobuf使用不當導致的程序內(nèi)存上漲問題

通過上面的代碼及圖5可以看出,Clear操作采用了遞歸的方式對Message中的逐個字段都進行了處理。對于基礎類型字段,代碼會對每個字段都設置默認值。對于一個非常長大的Message來說,消耗的CPU會非常多。相對于這種情況,釋放Message的內(nèi)存并重新申請小的空間,所占用CPU資源反而更少一些。在這個Case中,經(jīng)常出現(xiàn)Clear操作清理6、7M內(nèi)存的情況。這樣數(shù)據(jù)量的Clear操作與釋放Message,再申請200K Message空間比起來,顯然更消耗CPU資源。

7.   總結(jié)

protobuf的cache機制

protobuf message的clear()操作是存在cache機制的,它并不會釋放申請的空間,這導致占用的空間越來越大。如果程序中protobuf message占用的空間變化很大,那么最好每次或定期進行清理。這樣可以避免內(nèi)存不斷的上漲。這也是模塊內(nèi)存一直上漲的核心問題。

內(nèi)存監(jiān)控機制

需要對程序的各個模塊添加合適的監(jiān)控機制,這樣當某個module的內(nèi)存占用增加時,我們可以及時發(fā)現(xiàn)細節(jié)的問題,而不用從頭排查。根據(jù)這次的排查經(jīng)驗,后面會主導在產(chǎn)品代碼中添加線程/module級內(nèi)存和cpu處理時間的監(jiān)控,將監(jiān)控再往”下”做一層。

UT在內(nèi)存問題定位中的作用

在逐個對module進行排查時,UT驗證比在測試環(huán)境中更高效,當然前提是這些module的UT能夠比較容易的寫出來。這也是使用先進框架的一個原因。對于驗證環(huán)境代價高昂的模塊,UT驗證的效果更加明顯。

百度MTC是業(yè)界領先的移動應用測試服務平臺,為廣大開發(fā)者在移動應用測試中面臨的成本、技術和效率問題提供解決方案。同時分享行業(yè)領先的百度技術,作者來自百度員工和業(yè)界領袖等。

>>如有問題,歡迎與我溝通

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


新聞標題:Protobuf使用不當導致的程序內(nèi)存上漲問題-創(chuàng)新互聯(lián)
本文來源:http://www.dlmjj.cn/article/degigh.html