整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          實(shí)用干貨:AIX 進(jìn)程內(nèi)存分配與回收策略及應(yīng)用開發(fā)建議 | 運(yùn)維進(jìn)階

          【作者】陳熾卉,15年P(guān)ower服務(wù)器領(lǐng)域工作經(jīng)驗(yàn),高級(jí)技術(shù)支持中心性能調(diào)優(yōu)專家,紅皮書《Power Systems Guide: and 》主要作者之一。長(zhǎng)期在金融、電信行業(yè)從事技術(shù)支持工作;對(duì)應(yīng)用開發(fā)、系統(tǒng)優(yōu)化、故障定位、基準(zhǔn)測(cè)試等方面均有豐富經(jīng)驗(yàn)。

          目錄

          1. AIX 內(nèi)存分配回收策略

          1.1 內(nèi)存分配觀察示例—遞增分配

          1.2 內(nèi)存分配觀察示例—遞減分配

          1.3 針對(duì)長(zhǎng)運(yùn)行程序的空閑內(nèi)存回收

          1.4 mallopt 示例 1

          1.5 mallopt 示例 2

          1.6 內(nèi)存回收 策略

          1.7 / 代碼示例

          1.8 內(nèi)存碎片對(duì)內(nèi)存回收的影響

          1.9 通用建議

          2. 內(nèi)存監(jiān)控

          2.1 觀察系統(tǒng)中內(nèi)存占用最高的進(jìn)程

          2.2 尋找內(nèi)存持續(xù)增長(zhǎng)的進(jìn)程

          2.3 如何通過(guò)共享內(nèi)存 ID 對(duì)應(yīng)關(guān)聯(lián)到該共享內(nèi)存的進(jìn)程

          2.4 如何獲取 AIX Kernel 的內(nèi)存使用率

          2.5 如何判斷系統(tǒng)是否存在內(nèi)存不足

          3. 應(yīng)用開發(fā)工具

          3.1 dbx 使用以及 定位

          3.2 內(nèi)存非法使用檢查

          3.3 內(nèi)存泄漏檢查()

          3.4 內(nèi)存泄漏檢查示例

          3.5 介紹

          3.6 介紹

          3.7 如何將 C 文件與匯編文件對(duì)應(yīng)

          1.AIX 內(nèi)存分配回收策略

          一般而言, 系統(tǒng)會(huì)直接在進(jìn)程空間的free列表中維護(hù)其free釋放的內(nèi)存, 以供后續(xù)新的分配直接使用,這樣可以提高分配效率,不需要每次內(nèi)存分配都經(jīng)過(guò)系統(tǒng)內(nèi)核。進(jìn)程退出后,系統(tǒng)會(huì)回收該進(jìn)程占用的全部?jī)?nèi)存。

          注:選擇不同的分配策略時(shí),對(duì)空閑內(nèi)存空間的管理策略會(huì)有所差異。例如默認(rèn)的管理結(jié)構(gòu)是樹;而采用watson分配算法時(shí),使用的管理結(jié)構(gòu)是紅黑樹。

          笛卡爾樹參考結(jié)構(gòu):

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          1.1 內(nèi)存分配觀察示例—遞增分配

          進(jìn)程的詳細(xì)內(nèi)存分配情況可以使用svmon來(lái)觀察,參考如下示例。

          需要注意,為方便svmon觀察,示例代碼需要在malloc之后調(diào)用memset進(jìn)行初始化;因?yàn)椴僮飨到y(tǒng)實(shí)際上并不會(huì)立即對(duì)已申請(qǐng)但尚未訪問(wèn)到的內(nèi)容分配實(shí)際存儲(chǔ)空間, 而是推遲到第一次訪問(wèn)時(shí)才會(huì)實(shí)際分配---這即是缺頁(yè)機(jī)制的工作原理。

          如下是一個(gè)申請(qǐng)空間遞增的應(yīng)用,分配/釋放大小為2MB->4MB->8MB->16MB, 則通過(guò)各階段的svmon可以看到, 內(nèi)存頁(yè)面會(huì)持續(xù)增長(zhǎng), 從2MB一直增加到16MB (注意 不是2MB+4MB+..+16MB=30MB) 。

          Malloc分配2MB,未初始化時(shí):

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          Address Range為0~512頁(yè),即代表512×4096=2MB虛擬地址空間。Virtual取值為2,表示該空間尚未實(shí)際分配。

          初始化后:

          Virtual取值為513,表明虛存空間已經(jīng)實(shí)際分配。

          釋放之前申請(qǐng)的2MB,重新 申請(qǐng) 4MB 并初始化后:

          1024×4096=4MB,此前釋放的512頁(yè)虛擬地址空間被重復(fù)利用。

          釋放之前申請(qǐng)的4MB,重新 申請(qǐng)8 8 MB 并初始化后:

          此前釋放的1024頁(yè)虛擬地址空間被重復(fù)利用。

          釋放之前申請(qǐng)的8MB,重新 申請(qǐng) 16 MB 并初始化后:

          1.2 內(nèi)存分配觀察示例—遞減分配

          如示例, 如果是一個(gè)申請(qǐng)空間遞減的應(yīng)用, 分配/釋放大小為16MB->8MB->4MB->2MB, 通過(guò)各階段的svmon(svmon -nrP

          )可以看到,內(nèi)存頁(yè)面始終維持在16MB。

          Malloc分配16MB,未初始化時(shí):

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          Address Range為0~4096頁(yè),即代表4096×4096=16MB虛擬地址空間。Inuse/Virtual取值為2,表示該空間尚未實(shí)際分配。

          初始化后:

          Virtual=4097頁(yè), 虛擬內(nèi)存已經(jīng)實(shí)際分配。

          釋放之前申請(qǐng)的16MB,重新 申請(qǐng)8 8 MB 并初始化后:

          釋放之前申請(qǐng)的8MB,重新 申請(qǐng)4 4 MB 并初始化后:

          釋放之前申請(qǐng)的4MB,重新 申請(qǐng)2 2 MB 并初始化后:

          可以看到svmon輸出結(jié)果沒有變化;原因是雖然應(yīng)用調(diào)用了free釋放了16MB內(nèi)存,但系統(tǒng)的處理策略是將該內(nèi)存置于進(jìn)程自身的空間塊樹中管理。下一個(gè)8MB分配,實(shí)際上是直接從進(jìn)程已有的16MB空閑塊中獲取的。但對(duì)系統(tǒng)而言,進(jìn)程管理的空閑塊樹也對(duì)應(yīng)為該進(jìn)程的內(nèi)存消耗,所以其內(nèi)存占用沒有變化。

          測(cè)試代碼:

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          1.3 針對(duì)長(zhǎng)運(yùn)行程序的空閑內(nèi)存回收

          由于上面介紹的內(nèi)存使用方式,一個(gè)常見的現(xiàn)象是,對(duì)于長(zhǎng)運(yùn)行進(jìn)程,其占用的私有內(nèi)存大小等同于最高峰時(shí)間的內(nèi)存大小。

          這個(gè)現(xiàn)象一般而言,對(duì)系統(tǒng)正常運(yùn)行及性能的影響很小。因?yàn)槿绻到y(tǒng)空閑內(nèi)存足夠,這個(gè)問(wèn)題不存在。而如果內(nèi)存不足,由于進(jìn)程本身的空閑塊列表沒有被引用,根據(jù)換頁(yè)算法,在系統(tǒng)缺頁(yè)(即可用內(nèi)存不足)時(shí),很容易被換出。

          但如果應(yīng)用進(jìn)程希望對(duì)其空間內(nèi)存塊進(jìn)行更自主的管理,可以使用mallopt接口。例如,對(duì)長(zhǎng)運(yùn)行的程序,定期在其閑時(shí)(例如每周日凌晨業(yè)務(wù)量極低時(shí)),調(diào)用 mallopt(, 0)釋放進(jìn)程私有空間的free列表。這樣可以避免在程序本身沒有內(nèi)存泄漏的情況下,因業(yè)務(wù)高峰期大量的內(nèi)存申請(qǐng)?jiān)斐傻倪M(jìn)程私有free list增長(zhǎng),而使得進(jìn)程內(nèi)存占用過(guò)大。實(shí)現(xiàn)起來(lái)也相當(dāng)簡(jiǎn)單(參考如下 mallopt 示例)。

          參考mallopt函數(shù)的幫助信息:

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          1.4 mallopt 示例 1

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          1.5 mallopt 示例 2

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          1.6 內(nèi)存回收 策略

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          如果需要設(shè)置使得系統(tǒng)在應(yīng)用調(diào)用 free 之后,即回收其內(nèi)存,可以在程序啟動(dòng)前設(shè)置環(huán)境變量(這兩種方式都可能對(duì)程序性能有很大影響):

          PSALLOC=early或者=

          由于PSALLOC=early實(shí)際上意味著設(shè)置=,且提前分配Paging Space;所以其性能開銷還要高于=。但這種機(jī)制能夠避免Paging Space耗盡時(shí),進(jìn)程被系統(tǒng)kill掉的可能;詳情可以通過(guò)在如下aix 網(wǎng)站查詢PSALLOC獲取。

          注:

          老的=3.1也有此效果,但該分配策略往往性能一般,且只適用于32位程序,現(xiàn)在的系統(tǒng)一般不使用了。

          在設(shè)置環(huán)境變量=watson的情況下,mallopt(,0)無(wú)效;

          mallopt(,0)只對(duì)系統(tǒng)默認(rèn)的分配策略(即樹分配算法)有效。

          也可以在代碼中直接用調(diào)用。注意 調(diào)用需要在 free /delete 之前;超過(guò) 4G 的內(nèi)存塊需要使用 函數(shù)。

          1.7 / 代碼示例

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          1.8 內(nèi)存碎片對(duì)內(nèi)存回收的影響

          需要注意的是,上面各種釋放進(jìn)程私有空閑內(nèi)存列表的方法,在應(yīng)用出現(xiàn)嚴(yán)重內(nèi)存碎片的情況下,都存在不足。這種情況需要實(shí)際應(yīng)用程序通過(guò)合理設(shè)計(jì),避免嚴(yán)重內(nèi)存碎片。

          例如一些緩存數(shù)據(jù)庫(kù)表的數(shù)據(jù)結(jié)構(gòu),可能涉及大量記錄的增刪,且一般不會(huì)一次性全部刪除,類似這種情況可能最終造成嚴(yán)重內(nèi)存碎片;從而使得進(jìn)程私有空間無(wú)法有效回收, 只能存在于進(jìn)程自身的私有free list中。

          舉一個(gè)極端的例子,一個(gè)進(jìn)程申請(qǐng)了4000頁(yè)內(nèi)存,但釋放時(shí),恰好在每個(gè)內(nèi)存頁(yè)上保留了一個(gè)16字節(jié)的數(shù)據(jù)結(jié)構(gòu)(其他空間均釋放)。這樣進(jìn)程的私有內(nèi)存空間實(shí)際上無(wú)法進(jìn)行收縮。因?yàn)閙allopt(, 0)和等方法都需要以多個(gè)頁(yè)面為單位進(jìn)行實(shí)際回收。

          但如果應(yīng)用設(shè)計(jì)良好,一般可以避免這類問(wèn)題:例如一些事務(wù)性的應(yīng)用,在事務(wù)處理開始時(shí),大量申請(qǐng)內(nèi)存;在處理結(jié)束后, 就將這些內(nèi)存釋放。這種情況下, 出現(xiàn)大量?jī)?nèi)存碎片的概率較低。

          1.9 通用建議

          一般對(duì)內(nèi)存受限程序的建議是:

          a. 盡量使用malloc而不是calloc

          b. 提高引用局部性,即僅在數(shù)據(jù)結(jié)構(gòu)馬上要被使用前,對(duì)其進(jìn)行初始化。

          c. 對(duì)大的數(shù)據(jù)結(jié)構(gòu),如果使用一次后,后續(xù)不再使用,建議調(diào)用回收其分配的內(nèi)存。

          參考:

          性能管理和調(diào)整 > 性能管理 > 性能規(guī)劃和實(shí)現(xiàn) > 有效的程序設(shè)計(jì)和實(shí)現(xiàn) > 內(nèi)存限制程序:

          要將數(shù)據(jù)工作集減至最小,請(qǐng)嘗試集中常用數(shù)據(jù)以及避免對(duì)虛擬存儲(chǔ)器頁(yè)面不必要的引用。

          特別是:

          i. 用 malloc() 或 calloc() 子例程來(lái)僅請(qǐng)求實(shí)際需要的空間大小。當(dāng)實(shí)際情況只使用數(shù)組的一小部分時(shí),切勿請(qǐng)求然后初始化最大的數(shù)組。當(dāng)您得到一個(gè)新頁(yè)面用來(lái)初始化數(shù)組元素時(shí),您實(shí)際上是強(qiáng)制 VMM 從別處竊取一個(gè)實(shí)內(nèi)存頁(yè)面。隨后, 當(dāng)擁有該頁(yè)面的進(jìn)程嘗試再次訪問(wèn)它時(shí),會(huì)造成缺頁(yè)故障。malloc() 和 calloc() 子例程的差異不僅僅在接口上。

          ii. 因?yàn)?calloc() 子例程將分配的存儲(chǔ)器置零, 它與每一個(gè)分配的頁(yè)面相關(guān), 而 malloc() 子例程只與第一個(gè)頁(yè)面相關(guān)。如果您用 calloc() 子例程分配一大塊區(qū)域, 然后最初只使用一小部分,那么您對(duì)系統(tǒng)施加了不必要的負(fù)載。不僅這些頁(yè)面必須初始化;而且如果它們的實(shí)內(nèi)存頁(yè)面被系統(tǒng)回收(因?yàn)橄到y(tǒng)調(diào)頁(yè)), 那么已初始化但從未使用的頁(yè)面必須寫出到調(diào)頁(yè)空間。這種情況浪費(fèi) I/O 和調(diào)頁(yè)空間。

          iii. 大結(jié)構(gòu)(如緩沖區(qū))的鏈表可以引起類似的問(wèn)題。如果您的程序執(zhí)行大量尋找某個(gè)特定關(guān)鍵字的鏈?zhǔn)礁櫍?qǐng)考慮保持鏈接指針和關(guān)鍵字與數(shù)據(jù)分離或使用散列表方法來(lái)代替。

          iv. 引用局部性也意味著時(shí)間上的局部性, 而不僅僅是地址空間上。僅在使用之前初始化數(shù)據(jù)結(jié)構(gòu)(如果使用的話)。在重負(fù)載系統(tǒng)中,在初始化和使用之間長(zhǎng)時(shí)間駐留的數(shù)據(jù)結(jié)構(gòu)有幀被竊取(因?yàn)橄到y(tǒng)調(diào)頁(yè))的危險(xiǎn)。然后您的程序就會(huì)在開始使用數(shù)據(jù)結(jié)構(gòu)時(shí)發(fā)生不必要的缺頁(yè)故障。

          v. 同樣,如果早先使用一個(gè)大結(jié)構(gòu),然后與程序剩余部分無(wú)關(guān)聯(lián),它應(yīng)該被釋放。使用 free()子例程來(lái)釋放由 malloc() 或 calloc() 子例程分配的空間是不夠的。free() 子例程僅僅釋放結(jié)構(gòu)占用的地址范圍。要釋放實(shí)內(nèi)存和調(diào)頁(yè)空間,也可使用 () 子例程來(lái)放棄空間。對(duì)() 的調(diào)用應(yīng)該在調(diào)用 free() 之前進(jìn)行。

          2. 內(nèi)存監(jiān)控

          2.1 觀察系統(tǒng)中內(nèi)存占用最高的進(jìn)程

          后臺(tái)運(yùn)行 3 個(gè) nmem64 進(jìn)程:

          ./nmem64 -m 2048 -s 3000 -z 80 &

          按進(jìn)程使用的虛擬內(nèi)存進(jìn)行排序,顯示占用最高的前三項(xiàng):

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          顯示虛擬內(nèi)存占用最高的 3 個(gè)進(jìn)程的詳細(xì)的內(nèi)存段分布信息,如下:

          可以看到,消耗最多虛擬內(nèi)存的段都是 nmem64 進(jìn)程的數(shù)據(jù)段。

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          2.2 尋找內(nèi)存持續(xù)增長(zhǎng)的進(jìn)程

          可以使用 ps vg 記錄當(dāng)前系統(tǒng)中各進(jìn)程的內(nèi)存消耗情況,然后通過(guò)比較多次 ps vg 的結(jié)果來(lái)判斷是否存在一些進(jìn)程有持續(xù)的內(nèi)存增長(zhǎng)。

          說(shuō)明:

          進(jìn)程存在持續(xù)內(nèi)存增長(zhǎng)并不一定意味著出現(xiàn)了內(nèi)存泄漏。由于 AIX 內(nèi)存分配采用了訪問(wèn)時(shí)分配的策略, 進(jìn)程申請(qǐng)大量?jī)?nèi)存時(shí)系統(tǒng)并不會(huì)第一時(shí)間分配內(nèi)存, 而是在進(jìn)程使用過(guò)程中實(shí)際訪問(wèn)時(shí)才進(jìn)行分配。由于這種分配策略, 進(jìn)程在啟動(dòng)初期可能存在內(nèi)存持續(xù)增長(zhǎng)的可能 (例如數(shù)據(jù)庫(kù)緩存需要一定時(shí)間才能完全填充) ;但其增長(zhǎng)曲線應(yīng)該是收斂到具體值的。

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          測(cè)試腳本如下:

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          2.3 如何通過(guò)共享內(nèi)存 ID 對(duì)應(yīng)關(guān)聯(lián)到該共享內(nèi)存的進(jìn)程

          在 AIX 系統(tǒng)層面,只要給定共享內(nèi)存 id,就可以獲取 attach 該共享內(nèi)存的進(jìn)程列表,方法如下:

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          可以根據(jù)其共享段 SID,獲得相應(yīng)的關(guān)聯(lián)進(jìn)程 pid,如下。注意 ipcs 上看 NATTACH=53,即有 53 個(gè)進(jìn)程 attach 到該共享內(nèi)存,因此 svmon 結(jié)果中,進(jìn)程列表部分對(duì)應(yīng)列出了 53 個(gè)進(jìn)程 pid。

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          根據(jù)相應(yīng)的 pid 可以獲取進(jìn)程的具體信息:

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          2.4 如何獲取 AIX Kernel 的內(nèi)存使用率

          kernel大部分內(nèi)存占用采用跟普通進(jìn)程一樣的內(nèi)存段方式組織, 比如kernel heap(這部分內(nèi)存消耗包含文件系統(tǒng)的元數(shù)據(jù)、內(nèi)核擴(kuò)展、第三方驅(qū)動(dòng)等等), 網(wǎng)絡(luò)buffer,磁盤管理LVM buffer占用, 以及一些RAS特性的buffer占用, 例如light-weight memory trace buffers, 等等。這部分都可以通過(guò)svmon -Ss 查詢出( 注意這條命令阻塞時(shí)間較長(zhǎng))。

          少部分采用非段方式組織的主要是AIX內(nèi)存管理的元數(shù)據(jù)如頁(yè)表之類。

          可以通過(guò) perfpmr.sh - - x .sh 獲取kernel內(nèi)存占用的整體情況,內(nèi)存分布將輸出在perfpmr.int中。

          也可以通過(guò)如下方法直接觀察 AIX Kernel 內(nèi)存使用情況:

          1. 觀察AIX內(nèi)存使用的命令(基于kdb,建議僅在測(cè)試環(huán)境驗(yàn)證)

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          2. 建議

          從我們目前實(shí)驗(yàn)的幾個(gè)系統(tǒng)看,超過(guò)100G的大分區(qū),一般內(nèi)核的內(nèi)存占用實(shí)際都在 5%以下。如果客戶環(huán)境中采用了較多第三方驅(qū)動(dòng)或組件,比例可能偏高一些,建議搭建環(huán)境驗(yàn)證一下。

          此外, 如果系統(tǒng)中存在超大的JFS2文件系統(tǒng), 包含大量的巨型文件 (比如單個(gè)文件數(shù)十、 數(shù)百GB) ,或者有數(shù)以十萬(wàn)、百萬(wàn)計(jì)的小文件;則可能觀察到較高的JFS2 元數(shù)據(jù)緩存占用,或者inode緩存占用。這部分內(nèi)存消耗也會(huì)計(jì)入AIX kernel,可以通過(guò) cat/proc/sys/fs/jfs2/觀察到:

          # cat /proc/sy s/fs/jfs2/

          cache:

          inode cache:

          total:

          另,文件系統(tǒng)的元數(shù)據(jù)緩存和inode緩存可以通過(guò)如下ioo參數(shù)控制

          這兩個(gè)參數(shù)是比例系數(shù),設(shè)置為400時(shí),元數(shù)據(jù)和inode緩存最多能占據(jù)系統(tǒng)內(nèi)存的16%左右。

          一般而言,如果分區(qū)內(nèi)存不大或者元數(shù)據(jù)相關(guān)操作不多,使用默認(rèn)值(AIX7.1為200)通常是可行的。但如果分區(qū)內(nèi)存足夠大(比如100GB以上),元數(shù)據(jù)操作較多,則可以考慮將這兩個(gè)參數(shù)設(shè)置為100,可以使得元數(shù)據(jù)和inode緩存最多占用系統(tǒng)內(nèi)存的比例下調(diào)至4%左右。

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          2.5 如何判斷系統(tǒng)是否存在內(nèi)存不足

          預(yù)期的內(nèi)存需求是 virtual 頁(yè)面數(shù)加上文件頁(yè)面數(shù)(包括 pers 和 clnt) ,如果這兩者之和大于實(shí)際配置的內(nèi)存頁(yè)面數(shù),即可認(rèn)為存在內(nèi)存不足,如下示例:

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          AIX 6.1 TL2版本之后,加入了一個(gè)新的列:

          The "" means number of bytes of memory that can be used without paging working storage.

          計(jì)算大致的公式是: = free + numperm - min(numperm,minperm)- minfree

          注:numperm即文件緩存所占內(nèi)存;minperm為文件系統(tǒng)內(nèi)存需要保障的比例(minperm%)換算得到的內(nèi)存需求;minfree是系統(tǒng)內(nèi)存池需要保持的空閑容量(vmo參數(shù)); 如果不夠了,就會(huì)開始 paging 了, 這是目前最直接的判斷方法。

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          3.4 應(yīng)用開發(fā)工具

          3.1 dbx 使用以及 定位

          Core dump 定位參考:

          使用參考“General ” “調(diào)試程序”部分。下載地址:

          3.2 內(nèi)存非法使用檢查

          大部分的 都與內(nèi)存非法使用有關(guān)。IBM 是解決這類問(wèn)題的最佳工具。

          使用 Purify 插樁編譯后再進(jìn)行功能測(cè)試, 如果測(cè)試中發(fā)現(xiàn)內(nèi)存非法使用之類 (包括內(nèi)存泄漏)的問(wèn)題, Purify 可以提供 GUI 界面直接關(guān)聯(lián)到出現(xiàn)問(wèn)題的應(yīng)用源代碼, 這樣能夠很方便的定位內(nèi)存使用類的問(wèn)題。

          此外, 組件可以用于分析程序的性能問(wèn)題。這些工具功能都非常完備。

          AIX 下可免費(fèi)使用的非法內(nèi)存使用檢查工具是 Malloc Debug Tool,設(shè)置好 和 選項(xiàng)后, 啟動(dòng)程序即可打開 malloc 調(diào)試功能。如下是常用的一組選項(xiàng):

          =debug

          ="log,,,,,,,output:/tmp/.txt"

          如果允許越界讀(一般情況下不會(huì)造成嚴(yán)重錯(cuò)誤) ,可以在 中加入。

          打開 后默認(rèn)的行為是發(fā)現(xiàn)內(nèi)存使用錯(cuò)誤后調(diào)用 abort 終止程序,這樣可以在第一時(shí)間 core dump 并退出,方便定位問(wèn)題。但如果不希望終止可以使用 參數(shù),這樣對(duì)于可以恢復(fù)的錯(cuò)誤,將僅生成 core,進(jìn)程會(huì)繼續(xù)執(zhí)行。

          或:

          =",log:,:8,,,,,,output:/tmp/.txt"

          具體可以參考:

          注意:

          使用 選項(xiàng)之后,為調(diào)試之目的,系統(tǒng)的內(nèi)存使用可能會(huì)成倍增加,所以需要事先預(yù)留好系統(tǒng)的可用內(nèi)存。

          3.3 內(nèi)存泄漏檢查()

          / 環(huán)境變量選項(xiàng)也可以用于內(nèi)存泄露檢查,如:

          =debug

          =",output:/tmp/.txt"

          更詳細(xì)的記錄:

          =debug

          =",log:,:6,output:/tmp/.txt"

          原理:

          選項(xiàng)可以用于幫助發(fā)現(xiàn)內(nèi)存泄露問(wèn)題, 選項(xiàng)采用數(shù)據(jù)庫(kù)記錄所有分配情況:當(dāng)成功分配內(nèi)存時(shí),采用數(shù)據(jù)庫(kù)記錄分配情況;而在該內(nèi)存被釋放時(shí),則從數(shù)據(jù)庫(kù)從刪除分配記錄;

          當(dāng)進(jìn)程退出時(shí),系統(tǒng)將所有未釋放內(nèi)存的詳細(xì)信息記錄到日志中。

          注意事項(xiàng):

          1. 從上面的原理介紹可以看到, 程序必須退出之后才能確切知道那些內(nèi)存沒有對(duì)應(yīng)的釋放操作。因此如果是長(zhǎng)運(yùn)行的程序,必須注冊(cè)一個(gè)退出函數(shù),常見的方法是注冊(cè)一個(gè)信號(hào)處理函數(shù),在收到 SIGTERM 或 SIGINT 時(shí)調(diào)用 exit(0) ,參考如下示例 ( 定義和注冊(cè)過(guò)程代碼已用紅色標(biāo)注)。

          2. 上述 debug 環(huán)境變量應(yīng)該設(shè)置為僅僅對(duì)目標(biāo)測(cè)試程序生效,不能直接在用戶環(huán)境中export,否則將造成大量無(wú)關(guān)程序的分配信息被記錄到日志中,對(duì)定位問(wèn)題造成干擾。

          3. 激活 Malloc log 之后,對(duì)于 32 位程序,每次內(nèi)存分配大約有 50-100 字節(jié)的額外開銷;對(duì) 64 位程序,每次內(nèi)存分配有 100-200 字節(jié)的額外開銷。因此,激活調(diào)試選項(xiàng)的應(yīng)用的內(nèi)存使用量會(huì)有一定的增長(zhǎng),在測(cè)試時(shí)需要預(yù)先準(zhǔn)備足夠的系統(tǒng)內(nèi)存。

          4. 示例如下:

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          參考文章:

          3.4 內(nèi)存泄漏檢查示例

          示例 1(基本輸出) :

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          示例 2(擴(kuò)展輸出) :

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          3.5 介紹

          AIX 提供了一系列基于/proc 文件系統(tǒng)的 工具集用于分析應(yīng)用問(wèn)題,例如 用于打印進(jìn)程當(dāng)前的棧信息;procldd 顯示進(jìn)程加載的共享庫(kù)信息; 顯示進(jìn)程打開的文件信息;procwdx 顯示進(jìn)程當(dāng)前的工作目錄;procsig 顯示進(jìn)程的信號(hào)處理規(guī)則(如SIGHUP,SIGTERM,SIGQUIT,SIGINT,SIGSEGV 等等) ; 顯示進(jìn)程的 、real、saved user ID 和 、real、saved group ID;

          參考:

          #wq513

          3.6 介紹

          AIX6.1 開始,AIX 提供了 功能,可以用于動(dòng)態(tài)跟蹤和調(diào)試。 的語(yǔ)法類似C 語(yǔ)言,參考:

          此外,AIX7.1 TL2 and AIX6.1 TL8 提供了新的 特性,即關(guān)聯(lián)數(shù)組" array".可以基于這個(gè)特性實(shí)現(xiàn)類似 truss –c 的功能。例如如下 aso.sh 示例,可以對(duì)進(jìn)程或系統(tǒng)范圍內(nèi)的調(diào)用進(jìn)行統(tǒng)計(jì)。

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          3.7 如何將 C 文件與匯編文件對(duì)應(yīng)

          優(yōu)化編譯可能會(huì)根據(jù)語(yǔ)義調(diào)整代碼位置,比如將循環(huán)不變量外提,賦值傳遞等等,這樣調(diào)試的難度會(huì)增加。調(diào)試-O2 -g程序時(shí), 打印的行信息可能并不準(zhǔn)確。這種情況有時(shí)需要結(jié)合匯編來(lái)分析,參考下面的例子:

          1. 使用 "-qsource -qlist"編譯選項(xiàng), 使用該選項(xiàng)后,針對(duì)每個(gè)源碼文件,編譯器都會(huì)生成一個(gè)對(duì)應(yīng)的".lst"文件,該文件提供了匯編和C/C++語(yǔ)句的對(duì)應(yīng)關(guān)系。

          2. 每個(gè)".lst"文件都有兩個(gè)部分,

          a. 一部分是源碼與行號(hào):

          8 | j = i / 7;

          b. 另一部分是相應(yīng)源碼行號(hào)對(duì)應(yīng)的匯編碼;

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          注意一些語(yǔ)句可能沒有直接對(duì)應(yīng)的匯編定義, 比如變量定義, 或者一些已經(jīng)被優(yōu)化掉的邏輯之類。

          參考如下示例:

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能存儲(chǔ)該文件_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令

          未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能儲(chǔ)存到所選驅(qū)動(dòng)器_未能存儲(chǔ)該文件

          未能打開元數(shù)據(jù)文件 存儲(chǔ)空間不足,無(wú)法處理此命令_未能存儲(chǔ)該文件_未能儲(chǔ)存到所選驅(qū)動(dòng)器

          參考文檔:

          原題:AIX 進(jìn)程內(nèi)存分配與回收策略及應(yīng)用開發(fā)建議


          主站蜘蛛池模板: 亚洲一区二区三区久久| 国产福利一区二区| 日本成人一区二区三区| 亚洲午夜日韩高清一区| 无码人妻啪啪一区二区| 日本强伦姧人妻一区二区| 老熟女高潮一区二区三区| 国产精品久久亚洲一区二区| 国产无线乱码一区二三区| 精品人妻AV一区二区三区 | 2021国产精品一区二区在线| 亚洲国产综合无码一区二区二三区 | 亚欧成人中文字幕一区| 久久精品一区二区国产| 精品亚洲综合在线第一区| 青娱乐国产官网极品一区| 一本一道波多野结衣AV一区| 亚洲视频一区在线播放| 日本一区二区免费看| 亚洲无线码一区二区三区| 亚洲日韩激情无码一区| 国语精品一区二区三区| 亚洲福利一区二区| 国产精品亚洲午夜一区二区三区 | 无码毛片一区二区三区视频免费播放 | 亚洲色欲一区二区三区在线观看| 理论亚洲区美一区二区三区| 在线精品自拍亚洲第一区| 人成精品视频三区二区一区| 中文字幕AV一区二区三区| 国产凸凹视频一区二区| 本免费AV无码专区一区| 精品性影院一区二区三区内射| 91一区二区视频| 鲁大师成人一区二区三区| 日韩精品在线一区二区| 国产麻豆精品一区二区三区| 538国产精品一区二区在线| 久久精品国产AV一区二区三区| 精品一区二区三区在线观看l| 日韩精品无码久久一区二区三|