qt5.8版本qml的ListModel的内存泄露问题

  1. 云栖社区>
  2. 博客>
  3. 正文

qt5.8版本qml的ListModel的内存泄露问题

py_tty_0529 2018-07-13 13:53:41 浏览637
展开阅读全文

qt5.8版本的ListModel在实际应用中,其get函数存在内存泄露问题,在若程序作为常驻进程是涉及到ListModel.get的调用时会出现内存逐渐增加。

在不修改ListModel源码情况下,只能通过绕开get函数去除内存泄露的影响。

下面给出两个示例案例,其一是ListModel的数据项为普通数值,

其二是ListModel的数据项中包含其他qml对象,例如存在子ListModel等情况

其一:

    property var pCount : 0;
    property var pObj : {"id":0,"name":""};
    property var pval_ : "off";
    property var pObjs : [] //ListModel.get函数造成的内存泄漏,采用自定义数组规避get函数调用
    property var pval_On : "开";
    property var pval_Off : "关";
    property var existf : 0;
    property var index_ : 0;
    function addPDef(devID,pID,name,desc, pType,val)
    {
        existf = 0;
        pCount = pObjs.length;
        for (index_ = 0; index_ < pCount; index_++)
        {
            pObj = pObjs[index_];
            if(pObj.id===pID)
            {
                existf = 1;
                break;
            }
        }
        if(0==existf){
            pval_ = getVal(pType,val);
            pObj = {
                "id":pID,
                "pType":pType
            };
            pObjs.push(pObj);
            pObj = {
                "id":pID,
                "pType":pType,
                "name":name,
                "title":desc,
                "dtime":"",
                "val":pval_,
                "devid":devID
            };
            submodel.append(pObj);
        }
    }

    function pValue(pID,dtime,val)
    {
        pCount = pObjs.length;
        for (index_ = 0; index_ < pCount; index_++)
        {
            pObj = pObjs[index_];
            if(pObj.id===pID)
            {
                pval_ = getVal(pObj.pType,val);
                submodel.setProperty(index_,"dtime",dtime);//该函数不会内存泄露
                submodel.setProperty(index_,"val",pval_);
                break;
            }
        }
    }
    property var valStr : pval_Off;
    function getVal(pType,val)
    {
        valStr = val;
        if(1==pType||3==pType)
        {
            valStr = val>0?pval_On:pval_Off;
        }
        return valStr;
    }

其二:

    property var devModel : Qt.createComponent("content/ListPage.qml");
    property var devCount : 0;
    property var devObj : { "id": 0, "name": "" };
    property var devObjs: []//ListModel.get函数造成的内存泄漏,采用自定义数组尽量规避get函数调用
    property var existf : 0;
    property var index_dev : 0;
    function addDev(devid,devtype,name,desc)
    {
//        console.log("devID :", devid," devType :", devtype," name :", name," desc :", desc);
        existf = 0;
        devCount = devObjs.length;
        for (index_dev = 0; index_dev < devCount; index_dev++)
        {
            devObj = devObjs[index_dev];
            if(devObj.id===devid)
            {
//                console.log("dev:", desc,"is exist");
                existf = 1;
                break;
            }
        }
        if(0==existf){            
//            console.log("devObjs size=:", devObjs.length);
            devObj = {
                "id":devid,
                "dtype":devtype,
                "name":name,
                "title":desc,
                "page":devModel.createObject(devid)
            };
            pageModel.append(devObj);//ListModel包含了其他qml对象
            devObjs.push(pageModel.get(devObjs.length));//将ListModel的子项采用数组标记好
        }
    }

    function addPInfo(devID,pID,name,desc, pType,val)
    {
//        console.log("devID :", devID," pID :", pID," name :", name," desc :", desc," pType :", pType," val :", val);
        devCount = devObjs.length;
        for (index_dev = 0; index_dev < devCount; index_dev++)
        {
            devObj = devObjs[index_dev];
            if(devObj.id===devID)
            {
//                devObj = pageModel.get(index_dev);//暂时无法更好的办法规避
                devObj.page.addPDef(devID,pID,name,desc, pType,val);
                break;
            }
        }
    }

    function pValue(devID,pID,dtime,val)
    {
//        console.log("devID :", devID," pID :", pID," dtime :", dtime," val :", val);
        devCount = devObjs.length;
        for (index_dev = 0; index_dev < devCount; index_dev++)
        {
            devObj = devObjs[index_dev];
            if(devObj.id===devID)
            {
//                devObj = pageModel.get(index_dev);//暂时无法更好的办法规避
                devObj.page.pValue(pID,dtime,val);
                break;
            }
        }
    }

调整前,通过测试用例喂数据,程序运行一天就能增长10多倍,经过调整后的程序进行常驻运行一个星期,其内存一直稳定在25M左右浮动,测试有效。

等再进行qt5.8版本的源码静态编译部署时顺道把ListModel.get函数源码修改一下,直接采用get函数实现可以节省很多逻辑。

网友评论

登录后评论
0/500
评论
py_tty_0529
+ 关注