1. 程式人生 > >QT程式佔用記憶體過高

QT程式佔用記憶體過高



1.問題:

   最近正在測試寫的QT應用程式,QT程式執行在S3C2440板子上的linux系統中,測試的過程中發現一個奇怪的問題,QT程式佔用記憶體一次比一次大。比如第一次開機QT應用程式執行記憶體為30M,在執行一段時間後增加到33M,此時我將板子斷電。第二次上電重啟,怪事發生了,此時執行記憶體達到了34M,執行一段時間後達到37M。依次類推,最後QT程式因為佔用記憶體過大被linux系統直接殺掉了,後面直接就起不來了。這個問題我百思不得其解,按理即使有記憶體洩露,斷電重啟它應該也會復原啊,為何記憶體卻一次比一次大呢?

2.原因:

   經過多天的查詢終於找到了故障點,原來是因為我程式中使用了SQLite資料庫導致的。具體的原因是,我在QT程式中使用SQLite資料庫存取歷史資料,存取的歷史資料是由下位機傳上來的,每5秒存一次,這樣每天存取的資料量達到17280條,量比較大。而導致記憶體一次比一次大的根本原因就在於我獲取資料庫最後一條記錄的操作方式,由於我使用檔案號的形式存取資料,所以每次儀器開機時都要去檢視資料庫中最後一條歷史記錄的檔案號,然後以此檔案號為基礎向資料庫中新增歷史記錄(檔案號唯一代表每條歷史記錄,不能重複)。下面是我獲取檔案號的程式碼:

QSqlQuery history_query;

    history_query.exec("SELECT * FROM history");

    if(!history_query.next())

    {

        g_iFileNum = 0;

    }

    else

    {

        history_query.last();

        g_iFileNum = history_query.record().value("FileNumber").toInt() + 1;

    }

錯誤點就在於last()函式的使用,last()函式會將資料庫中所有的記錄都放到了

history_query的緩衝區中,如果資料庫中history表資料量龐大的話就會造成記憶體急劇攀升,此段程式碼在主介面的建構函式之中,以後隨著歷史記錄的增多,開機記憶體會越來越大,以致出現上述故障。

注意:下面這種獲取最後一條歷史記錄的方式同樣會造成上述故障。

QSqlTableModel *model;  //用於顯示歷史記錄

    model = new QSqlTableModel(this);

model->setTable("history");

model->setEditStrategy(QSqlTableModel::OnFieldChange);

    model->select();

    while (model->canFetchMore())

    {

//        model->clear(); //使用clear不能達到預期效果,即無效

          model->fetchMore();

    }

    int row_num = model->rowCount();

    g_iFileNum = model->record(row_num - 1).value("FileNumber").toInt() + 1;

3.解決方案:

    我的解決方案就是使用排序來獲取最後一條歷史資料,實驗表明此種方式將避免上述出現的問題,效果良好,程式碼如下:

    //

    // 歷史記錄部分的處理

//

QSqlTableModel *model;  //用於顯示歷史記錄

    model = new QSqlTableModel(this);

    model->setTable("history");

    model->setEditStrategy(QSqlTableModel::OnFieldChange);

    /* 獲取檔案號(取檔案號最好不要用last函式或者fetchMore函式,資料庫大時會造成系統崩潰) */

    model->setSort(0,Qt::DescendingOrder);  //降序排列

    model->select();

    model->query().first(); //必須使用,因為排序後當前行不是第一行,而是第255行

    g_iFileNum = model->query().record().value("FileNumber").toInt() + 1;

    /* 獲取檔案號後將資料庫恢復為升序排列 */

    model->setSort(0,Qt::AscendingOrder);  //升序排列

    model->select();