C++ 使用QThread和QPrinter时内存泄漏
我正在使用C++ 使用QThread和QPrinter时内存泄漏,c++,qt,memory-leaks,qt5,qprinter,C++,Qt,Memory Leaks,Qt5,Qprinter,我正在使用QThread通过QPrinter 我的PrintWorker如下所示: class PrintWorker : public QObject { Q_OBJECT public: PrintWorker(QThread*, QPrinter*, QPicture*, QPainter*, QObject *parent = 0); private: QPicture *_picture = nullptr; QPrinter *_printer =
QThread
通过QPrinter
我的PrintWorker
如下所示:
class PrintWorker : public QObject {
Q_OBJECT
public:
PrintWorker(QThread*, QPrinter*, QPicture*, QPainter*, QObject *parent = 0);
private:
QPicture *_picture = nullptr;
QPrinter *_printer = nullptr;
QPainter *_painter = nullptr;
public slots:
void print();
signals:
void done();
};
PrintWorker::PrintWorker(QThread *thread, QPrinter *printer, QPicture *picture, QPainter *painter, QObject *parent) :QObject(parent),
_picture(picture), _printer(printer), _painter(painter)
{
moveToThread(thread);
QObject::connect(thread, &QThread::started, this, &PrintWorker::print);
QObject::connect(this, &PrintWorker::done, thread, &QThread::quit);
QObject::connect(this, &PrintWorker::done, this, &PrintWorker::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
}
void PrintWorker::print() {
// do some print job with painter and picture
emit done();
}
而print
的方法是:
void NewService::print() {
if (!_printer) { /* _printer : a private member */
_printer = new QPrinter(QPrinter::HighResolution);
_printer->setPageSize(QPrinter::A5);
_printer->setPageOrientation(QPageLayout::Portrait);
_printer->setColorMode(QPrinter::Color);
}
if (!_printDialog) { /* _printDialog : a private member */
_printDialog = new QPrintDialog(_printer);
}
if (_printDialog->exec() == QPrintDialog::Accepted) {
MyWidget *widget = new MyWidget(/* some args*/);
QPainter *painter = new QPainter;
QPicture *picture = new QPicture;
widget->render(picture);
QThread *thread = new QThread;
PrintWorker *worker = new PrintWorker(thread, _printer, picture, painter);
thread->start();
}
}
现在,在调用print()
之前,我的应用程序在打印和调用PrintWorker::print()
之后会暴露大约9MB的内存,我的应用程序的内存使用量达到26MB
在另一个世界中,如果我们删除PrintWorker::print()
中最后一部分的emit done
,则没有什么区别
完成作业后,我们希望内存使用量降至26MB-线程空间+\u打印机
+\u打印对话框
对象大小≈ 14MB
那么这又有什么问题呢?您正在删除
PrintWorker
和QThread
对象,但不是qPaint
,QPicture
,MyWidget
,QPrintDialog
或QPrinter
。这些是内存泄漏(new
,没有delete
)。请注意,PrintWorker
析构函数可以负责删除QPainter
、QPicture
和QPrinter
,此外,它还可以拥有MyWidget
并删除它。希望QPrintDialog
对象被NewService
类删除,但很难说,因为代码没有发布
此外,根据rafael gonzalez的建议,您应该检查QThread
PrintWorker
和QThread
是否实际被删除
顺便问一下,你是如何检查内存使用情况的?通过泄漏检测工具(如valgrind、VLD…)?或通过Windows任务管理器。因为任务管理器肯定是不可靠的。通过调用
QThread::quit()
您正在主动退出此线程中的EventLoop。驻留在此线程中的对象的QObject::deleteLater()
可能不再执行(尽管它们在QThread::finished()
-上提到,仍将调用delete later插槽)
我个人只需要使用finished()
信号设置连接,或者将worker对象的父对象设置为线程本身,然后Qt实际上必须删除该对象
您是否尝试添加qDebug查看是否调用了打印工作人员的析构函数?@rafaelgonzalez.Yes
PrintWorker::~PrintWorker()
被调用。是的,测量工具是Windows任务管理器,也是的PrintWorker::~PrintWorker()调用,但我没有得到它,我将线程对象设为私有,并设置QObject::connect(_printThread,&QThread::destromed,this,&NewService::onPrintDone)
现在我看到QObject(0x2647bb040f0)
通过qDebug()删除\u printThread
不会更改指针地址,即使删除,它仍可能显示QObject(0x2647bb040f0)
。另外,onPrintDone可以在deleteLater
机制实际删除QThread
之前调用。最后,任务管理器向您显示应用程序的内存使用情况,当您删除对象时,内存不一定会减少。您必须使用检漏仪工具。