【发布时间】:2017-03-15 08:35:37
【问题描述】:
大家好!
我在 Qt 5.8 上通过 QSerialBus 库实现 ModBus 时遇到问题。
问题是 - 当我尝试高速读取离散输入列表时,程序会发现内存泄漏 - 大约每秒 300-350Kb。
所以,这里是导致泄漏的函数代码:
void ModBus::queue()
{
if(!_readList.isEmpty())
{
if(!checkState())
{
_readList.clear();
_curPos = DiscInputPos::Full;
queue();
return;
}
QModbusDataUnit readData = QModbusDataUnit(QModbusDataUnit::DiscreteInputs, _readList.first(), 1);
if(auto *reply = _client->sendReadRequest(readData, _serverNum))
{
if(!reply->isFinished())
{
connect(reply, &QModbusReply::errorOccurred, [=] (QModbusDevice::Error e)
{
reply->deleteLater();
if(e == QModbusDevice::TimeoutError)
{
_readList.clear();
_curPos = DiscInputPos::Full;
stop();
start();
queue();
}
});
connect(reply, &QModbusReply::finished, this, [=]
{
if(reply->error() == QModbusDevice::NoError)
{
if(reply->result().valueCount() > 0)
{
_curPos = (DiscInputPos) reply->result().value(0);
if(_curPos == DiscInputPos::Clear)
_readList.removeFirst();
else
_readList.clear();
}
}
else
{
_readList.clear();
_curPos = DiscInputPos::Full;
}
reply->deleteLater();
queue();
});
}
else
delete reply;
}
else
{
delete reply;
_readList.clear();
_curPos = DiscInputPos::Full;
queue();
}
}
else
{
emit sendReadResult(_curPos);
_curPos = DiscInputPos::Full;
}
}
_client — QModbusTcpClient
bool checkState() — 没有什么特别的,除非检查连接状态。
_readList 的最大大小为 4。
如果我用_client->sendReadRequest 注释部分代码 - 一切正常,没有任何泄漏。谁能解释一下 - 它可能是什么?
提前致谢!
【问题讨论】:
-
也许 QApplication 的事件调度器没有太多时间来删除标记为“deleteLater”的对象(回复)?如果停止高速输入,内存会怎样?
-
我看到几个“删除回复”,但正常路径没有。
-
@AdrianMaire,是的。我是example。即使我使用
delete而不是deleteLater()- 没有任何变化。 -
@em2er,内存不会去任何地方。
-
@em2er 时间根本不考虑它。如果您将控制权交还给事件循环,则您保证在循环将控制权交给下一个事件处理程序之前处理所有删除。如果每个事件循环都被限制在一个线程中,时间问题就没有任何意义:一次只能发生一件事,而且时间的流逝是无法衡量的,并且不会影响那些删除的行为。跨度>
标签: c++ qt memory-leaks