我正在创建一个科学应用程序,它与两个设备通信(一个通过USB,一个通过串口),从中获取数据并将其呈现在GUI中。运行几个小时(2-5可能?)之后的原因不明,整个系统突然开始减速,一两分钟后根本没有任何响应。唯一的解决方案是使用电源按钮重新启动PC。 USB端口通信由该设备附带的代码处理,因此可能没问题。我唯一的提示是,原因可能是串口通信,这是我第一次实现的。但它也可能是其他任何东西(例如GUI)。我在Scientific Linux 5上运行它。要打开串口,我使用:
tti::tti(const char* port)
{
fd = open(port,
(O_RDWR | O_NOCTTY) & ~O_NONBLOCK); //opening the port
if (fd == -1)
{
std::cout<<"error in tti::tti(const char* port) while opening port"<<std::endl;
}
else
{
//setting parameters
struct termios options; //create the struct
tcgetattr(fd,&options); //get the current settings of the serial port
cfsetispeed(&options,B9600); //set read and write speed to 19200 BAUD
cfsetospeed(&options,B9600);
options.c_cflag &= ~PARENB; //set no parity
options.c_cflag &= ~CSTOPB; //set one stop bit
options.c_cflag &= ~CSIZE; //clear current data size setting
options.c_cflag |= CS8; //set 8 bit per work
options.c_cc[VMIN] = 2; //minimum amount of characters to read
options.c_cc[VTIME] = 10; //amount of time to wait for amount of data specified in VMIN in tenths of a second
options.c_cflag |= (CLOCAL | CREAD); //don't allow changing of port control + enable the receiver
if (tcsetattr(fd,TCSANOW,&options)!=0)
{
std::cout<<"error in tti::tti(const char* port) while setting options"<<std::endl;
}
}
}
然后我每隔约3秒钟使用这段代码,连续4次:
std::string tti::query(std::string input){
input+=10;
int bytes = 0;
bytes = write(hSerial, input.c_str(), input.size());
if(bytes < 1){
std::cout<<"error in tti::send(std::string input) "<<std::endl;
return "error: no bytes written";
}
bytes=0;
const int n=10;
char szBuffer[n +1]={0};
bytes = read(hSerial,szBuffer,n);
bytes = read(hSerial,szBuffer,n);
if(bytes < 1){
std::cout<<"error in tti::query(std::string input)"<<std::endl;
return "error: no bytes read";
}
std::string s2(szBuffer);
return s2;
}
您能否就如何找到这种行为的原因给我一些建议?我尝试用valgrind运行应用程序,我发现没有内存泄漏。我也尝试用cppcheck检查代码,什么也没发现。问题是应用程序不会崩溃 - 它正在运行,但没有响应。它从未在短时间内发生过。我等待它停止的最短时间是2小时,但是我也已经运行了2-3次而没有任何问题。
答案 0 :(得分:4)
该应用程序不必实际泄漏内存以解决内存问题。如果你不断分配更多内存来保存新数据,那么内存使用量将不受限制地扩展(直到你的系统行为与你所描述的非常相似),即使你实际上没有泄漏内存。
首先,只需观察top
或ps
中的内存使用情况。然后,如果你在没有释放它的情况下找不到永远使用内存的地方,你可以使用valgrind的massif
工具来查看哪些代码行负责堆的当前状态。
答案 1 :(得分:1)
您可以在批处理模式下运行top。在此模式下,您可以将其输出保存在文件中以便稍后进行分析:
top -b -n sample_delay_in_sec | tee log.log
此命令将输出打印到控制台并将其保存到log.log文件中。
有趣的输出可以是 CPU ,内存,交换。当然看看你是否有一些使用大量内存或/和CPU的进程。
答案 2 :(得分:0)
感谢您的回答!
我设法找到增加内存使用量的来源。事实上,“顶级”命令对我帮助很大。事实证明,我每秒分配大约1MB而不删除它!几个小时后,PC的所有物理内存被我的应用程序“吃掉”,所以它停止了一切。选择性地禁用我的部分代码并运行“top”,我发现该部分负责该问题。
原因是其他地方,而不是串口通信。在应用程序中,我有6个对象(同一类的实例)负责实时数据图。情节控制班的成员之一是指向情节本身的指针。每次GUI刷新时,我都会用新的绘图对象覆盖指针,而不删除旧的绘图对象。我以为它会被自动删除,但我错了。
void graphData::updateGraph () {
delete m_graph; //THIS LINE WAS MISSING
m_graph = new TGraph(m_xArray.GetSize(),m_xArray.GetArray(),m_yArray.GetArray());
//(...) some more code in this function
}
听起来很简单,但我花了一周的时间来解决这个问题。 ;)