开发的时候,一定要及时控制CPU使用率以及使用内存大小等三个问题(一个星期检查一次)

一直专注于功能的开发,没注意CPU和内存。昨天无意中发现两个问题:

1. 程序启动后,什么都没干,CPU就50%了(单核)。现在想找原因降低使用率,感觉无从下手,要是平时就注意这个问题就好了。

2. 程序随着功能的运行,内存不断增长。内存泄漏的情况也有,但很少,都是几K几K的增长,这个还不要紧。但是更关键的是,在线程中运行数据的时候,建立了几个超大Map,偏偏写了一句deleteLater即在线程运行完毕之后自动释放内存,同时也会释放这几个超大Map,但是你不知道QT库会何时删除这个线程啊,导致程序内存从20M一下子变成几百M,而且不会降低。我学聪明了,在Map数据不需要以后,就clear,这样不影响后面的逻辑。目前不知道还有没有别的因素需要控制。要开发一个完整的软件还真是不容易。

3. 内存占用大以后,程序反应很慢,可我的机子内存明明有16G之多,为什么还是慢呢?

-----------------------------------------------------------------------------

第一个问题:CPU占用率狂增,已经知道为什么了,因为按钮上的图片在不断的刷新显示,每秒都要读取8次图片资源并刷新。

有错误的代码如下:

void ToolButton::setMousePress(bool mouse_press)
{
    this->mouse_press = mouse_press; // 记录状态
    if(mouse_press) button_select = true;
    else button_select = false;
    //qDebug() << "mouse_press=" << mouse_press;
    //qDebug() << "button_select=" << button_select;
    update(); // UI 按下了就要有反应,所以必须重绘(估计会调用paintEvent函数)
}

void ToolButton::paintEvent(QPaintEvent *event)
{
    //qDebug() << "button_select=" << button_select;
    // UI qqq fixme 怎么在完全不动界面的情况下,也会永远不停的自绘?
    QPainter painter(this);
    if(mouse_over)
    {
        //qDebug() << "paintEvent 000 mouse_over";
        //绘制鼠标移到按钮上的按钮效果
        // UI 点击之后,瞬间就结束了。剩下的时间,都处于按钮的over状态,所以这时必须一直重绘
        if(mouse_press) {
            QPixmap pixmap;
            pixmap.load(pic_name1);
            setIcon(pixmap);
            if (button_number<=1) {
                setStyleSheet("color: #3D4A54; background : #C1F1FA;");
            }
            else setStyleSheet("color: #F5997B;"); // 小按钮变成红色
        }
    }
    else
    {
        // qDebug() << "paintEvent else";
        // 一般情况下
        if(button_select)
        {
            // UI 当按钮被按下以后,这个按钮的mouse_press总是处于true的状态,所以会不停的重绘
            // fixme 所有的按钮都是这样吗?效率太低?
            // qDebug() << "paintEvent 111 mouse_press";
            QPixmap pixmap;
            pixmap.load(pic_name1);
            setIcon(pixmap);
            setStyleSheet("color: #F5997B;"); // 红色,小按钮按下之后的文字前景色            
            if (button_number<=1) setStyleSheet("color: #3D4A54; background : #C1F1FA;");
        } else {
            // 总是执行
            // qDebug() << "paintEvent 222 else";
            QPixmap pixmap;
            pixmap.load(pic_name);
            setIcon(pixmap);
            //setStyleSheet("color: #646E76;");
            setStyleSheet("color: #3D4A54;"); // 灰色,小按钮取消选中之后的文字前景色
            if (button_number<=1) setStyleSheet("color: #3D4A54; background : #F4F4F4;");
        }
    }

    QToolButton::paintEvent(event);
}

正确的代码如下:

void ToolButton::setMousePress(bool mouse_press)
{
    this->mouse_press = mouse_press; // 记录状态
    // qDebug() << "mouse_press=" << mouse_press;
    if(mouse_press) {
        QPixmap pixmap(pic_name1); // UI 红色图片,这里最关键
        setIcon(pixmap);
        setIconSize(pixmap.size());
        if (button_number<=1) {
            setStyleSheet("color: #3D4A54; background : #C1F1FA;");
        }
    }
    else {
        QPixmap pixmap(pic_name);
        setIcon(pixmap);
        setIconSize(pixmap.size());
        if (button_number<=1) {
            setStyleSheet("color: #3D4A54; background : #F4F4F4;");
        }
    }

    // update(); // UI 按下了就要有反应,所以必须重绘(估计会调用paintEvent函数)。但是如果是换图片,就不必重绘了
}

void ToolButton::paintEvent(QPaintEvent *event)
{
    // Archi exp 曾经造成CPU满格,就是因为不断刷新。其实只要一次性刷新即可
    // 必须有条件才能执行函数内容,否则就会永久不间断刷新
    // 其实就是我没有理解这个函数,只有需要特殊效果的时候,才在这里画一下。
    // 之前8个按钮根据按钮的选择情况,永久不间断刷新。其实一次性设好图片即可,根本不必刷新
    // 而且是不断读入图片,并设置QSS,然后更新图像,比单纯使用GDI刷新复杂多了
    // 如果不是动态效果,而只是设置图片,根本不必在这里设置。只有某些动态GDI才需要这里设置

    QPainter painter(this);
    if(mouse_over)
    {
        // qDebug() << "paintEvent mouse_over"; // UI 鼠标进入按钮区域后,此处只执行一次
        // 可在这里绘制一些动态GDI效果,比如:
        // painterInfo(0, 100, 150);
    }
    else
    {
        // qDebug() << "paintEvent always";
    }

    QToolButton::paintEvent(event);
}

另外可参考的代码如下(一般不执行):

void ToolButton::setMousePress(bool mouse_press)
{
    this->mouse_press = mouse_press;
    update();
}

void ToolButton::paintEvent(QPaintEvent *event)
{
    if(mouse_over)
    {
        //绘制鼠标移到按钮上的按钮效果
        painterInfo(0, 100, 150);
    }
    else
    {
        if(mouse_press)
        {
            painterInfo(0, 100, 150);
        }
    }

    QToolButton::paintEvent(event);
}

-----------------------------------------------------------------------------

第二个问题:

-----------------------------------------------------------------------------

第三个问题:

posted @ 2015-07-29 17:54  findumars  Views(983)  Comments(0)    收藏  举报