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函数实现可以节省很多逻辑。