0

我正在创建一个科学应用程序,它与两个设备(一个通过 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 次更长的时间,没有任何问题。

4

3 回答 3

4

该应用程序不必为了出现内存问题而实际泄漏内存。如果您不断地分配更多内存来保存新数据,那么内存使用量将无限扩大(直到您的系统行为与您描述的非常相似),即使您实际上并没有泄漏内存。

首先,只需观察 or 中的内存使用top情况ps。然后,如果你找不到永远使用内存的地方而不释放它,你可以使用massifvalgrind 的工具查看哪些代码行负责堆的当前状态。

于 2012-08-24T18:06:16.483 回答
1

您可以在批处理模式下运行 top。在这种模式下,您可以将其输出保存在文件中以供稍后分析:

  top -b -n sample_delay_in_sec | tee log.log

此命令会将输出打印到控制台并将其保存到 log.log 文件中。

有趣的输出可以是CPUMemSwap。当然看看你是否有一些使用大量内存或/和 CPU 的进程。

于 2012-08-24T18:22:16.970 回答
0

谢谢您的回答!

我设法找到了增加内存使用的来源。确实,“top”命令对我帮助很大。事实证明,我每秒分配大约 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
}

听起来很简单,但我花了一周的时间来解决这个问题。;)

于 2012-08-31T14:35:21.027 回答