在工具实现的过程中,遇到了内存爆了的问题,部分模型的规模可以达到10的100次方方甚至1000次方。(工具的主要算法涉及到了递归,递归深度会很深,所以也用到了ulimit修改栈空间来缓解爆栈的问题,治标不治本。)有一...

在工具实现的过程中,遇到了内存爆了的问题,部分模型的规模可以达到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
本文标题为:c++ 对特定进程的内存监控


- C++ 数据结构超详细讲解顺序表 2023-03-25
- C语言详解float类型在内存中的存储方式 2023-03-27
- Qt计时器使用方法详解 2023-05-30
- ubuntu下C/C++获取剩余内存 2023-09-18
- Easyx实现扫雷游戏 2023-02-06
- 详解C语言中sizeof如何在自定义函数中正常工作 2023-04-09
- C语言qsort()函数的使用方法详解 2023-04-26
- C语言手把手带你掌握带头双向循环链表 2023-04-03
- c++ const 成员函数,返回一个 const 指针.但是返回的指针是什么类型的 const? 2022-10-11
- 我应该为我的项目使用相对包含路径,还是将包含目录放在包含路径上? 2022-10-30