c++ 對特定進程的內存監控


在工具實現的過程中,遇到了內存爆了的問題,部分模型的規模可以達到10的100次方方甚至1000次方。
(工具的主要算法涉及到了遞歸,遞歸深度會很深,所以也用到了ulimit修改棧空間來緩解爆棧的問題,治標不治本。)
有一個循環,這個循環迭代16次,但是可能程序在某一次迭代過程中,已經耗光了內存,再申請空間的時候,出現異常,導致將整個進程殺死。而我的想法是,當某一個迭代過程中,出現無法再申請內存的情況,就輸出內存申請失敗的提示信息,並跳過它,進行下一次的迭代,而不是將整個進程kill。

解決方法:
創建一個子線程,讓它每隔1秒去檢查 當前進程的內存占用,如果超過一定的比例,則跳過此次的迭代。
檢查當前進程的內存占用,是用shell腳本實現的,使用shell腳本進行對內存的查詢只需要兩三行即可。
當執行shell腳本的時候,要獲取其輸出結果,也就是該進程的內存占用。
具體代碼如下

 1 void detect_memory()
 2 {
 3 
 4     for(;;)
 5     {
 6         FILE *pf;
 7         char buffer[20];
 8 
 9         //執行內存檢測腳本
10         pf = popen("sh detect_memory.sh", "r");
11 
12         if(pf!=NULL){
13 
14             //buffer:enPAC進程占用的內存(KB)
15             //fread 將pf指向的內容,讀sizeof(buffer)個字節,讀一次,讀到buffer中
16             fread(buffer, sizeof(buffer), 1, pf);
17 
18             //used:將buffer轉成整型,單位為MB
19             short int used = atoi(buffer)/1024;
20             pclose(pf);
21 
22             //判斷enPAC占用的內存,超過一定比例,則將memory_flag=false
23             //同時break,讓dfs()進行return,結束此公式的search
24             if(100*used/total_mem > 70)
25             {
26                 memory_flag = false;
27                 cout<<"detect memory over the size  given"<<endl;
28                 break;
29             }
30         }else{
31             cout<<"未能檢測到enPAC進程所占內存"<<endl;
32             pclose(pf);
33         }
34 
35         //每隔5秒,對enPAC占用內存進行查詢
36         sleep(1);
37     }
38 
39 
40 }
41 
42 detect_mem_thread = thread(&Product_Automata::detect_memory,this);  //創建一個子線程進行內存監控
View Code

注:popen總是和pclose一起出現被使用的。popen() 創建一個管道,通過fork或者invoke一個子進程,然后執行command。popen返回該FIFO數據流的指針。fread(buffer, sizeof(buffer), 1, pf),fread 將pf指向的內容,讀sizeof(buffer)個字節,讀一次,讀到buffer中。

 

shell腳本如下:
#!/bin/bash
process="enPAC"        #進程名字
PID=$(ps x | grep $process | grep -v grep | awk '{print $1}')
size=` cat /proc/${PID}/status | grep RSS | tr -cd "[0-9]"`
echo $size


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM