0

私は、2つのデバイス(1つはUSB経由、もう1つはシリアルポート経由)と通信し、それらからデータを取得してGUIに表示する科学アプリケーションを作成しています。理由は不明ですが、数時間(2〜5かもしれませんが)実行した後、システム全体の速度が突然低下し始め、1〜2分後には何も応答しなくなりました。唯一の解決策は、電源ボタンで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

アプリは、メモリの問題を抱えるために実際にメモリをリークする必要はありません。新しいデータを保持するためにより多くのメモリを継続的に割り当てると、実際にメモリリークが発生していなくても、メモリ使用量は無制限に拡大します(システムが説明したように動作するまで)。

まず、topまたはでメモリ使用量を監視しますps。次に、メモリを解放せずに永久に使用する場所が見つからない場合はmassif、valgrindのツールを使用して、ヒープの現在の状態の原因となっているコード行を確認できます。

于 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

ご回答ありがとうございます!

私はなんとかメモリ使用量の増加の原因を見つけることができました。実際、「トップ」コマンドは私を大いに助けてくれました。削除せずに毎秒約1MBを割り当てていたことがわかりました!数時間後、PCのすべての物理メモリが私のアプリケーションによって「食べられ」たため、すべてが停止しました。コードの一部を選択的に無効にして「top」を実行すると、問題の原因となっている部分が見つかりました。

その理由は、シリアルポート通信ではなく、どこか別の場所にありました。このアプリケーションでは、リアルタイムのデータプロットを担当する6つのオブジェクト(同じクラスのインスタンス)がありました。プロット保持クラスのメンバーの1つは、プロット自体へのポインターでした。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
}

とてもシンプルに聞こえますが、この問題を解決するのに1週間かかりました。;)

于 2012-08-31T14:35:21.027 に答える