Используя Основанный на QT DLL в неспокойном приложении

Короткий ответ заключается в том, что пользователи не должны видеть это сообщение. Пользователи не должны создавать утечки памяти в унифицированном менеджере памяти.

То, что такие утечки происходят, является ошибкой Spark: SPARK-11293


Но если вы хотите понять причину утечки памяти, вот как я это сделал.

  1. Загрузите исходный код Spark и убедитесь, что вы можете его построить, и ваша сборка работает.
  2. В TaskMemoryManager.java добавьте дополнительные записи в acquireExecutionMemory и releaseExecutionMemory: logger.error("stack trace:", new Exception());
  3. Измените все остальные журналы отладки на ошибку в TaskMemoryManager.java. (Легче, чем вычисление конфигураций протоколирования ...)

Теперь вы увидите полную трассировку стека для всех распределений и освобождений. Постарайтесь сопоставить их и найти распределения без освобождения. Теперь у вас есть трассировка стека для источника утечки.

24
задан darron 27 January 2010 в 21:46
поделиться

2 ответа

Изучая код Qt, кажется, что QCoreApplication необходим для отправки общесистемных сообщений, таких как события таймера. Такие вещи, как сигнал / слоты и даже QThreads не зависят от него, если они не связаны с этими общесистемными сообщениями. Вот как я делаю это в разделяемой библиотеке (кроссплатформенным способом с использованием самого Qt), и на самом деле я вызываю exec , потому что processEvents () один не обрабатывает все.

У меня есть глобальное пространство имен:

// Private Qt application
namespace QAppPriv
{
    static int argc = 1;
    static char * argv[] = {"sharedlib.app", NULL};
    static QCoreApplication * pApp = NULL;
    static QThread * pThread = NULL;
};

У меня есть метод OpenApp в QObject (который перемещается), например:

// Initialize the app
if (QAppPriv::pThread == NULL)
{
    // Separate thread for application thread
    QAppPriv::pThread = new QThread();
    // Direct connection is mandatory
    connect(QAppPriv::pThread, SIGNAL(started()), this, SLOT(OnExec()), Qt::DirectConnection);
    QAppPriv::pThread->start();
}

А вот слот OnExec :

if (QCoreApplication::instance() == NULL)
{
    QAppPriv::pApp = new QCoreApplication(QAppPriv::argc, QAppPriv::argv);
    QAppPriv::pApp->exec();
    if (QAppPriv::pApp)
        delete QAppPriv::pApp;
}

Пока что, кажется, все работает нормально, я не уверен, нужно ли мне удалять приложение в В конце я обновлю свой ответ, если найду что-нибудь.

9
ответ дан dashesy 29 November 2019 в 00:28
поделиться

Документация Qt для 4.5.2 гласит, что аргументы QCoreApplication должны иметь время жизни, равное периоду объекта приложения, поэтому вам не следует использовать локальные переменные.

Помимо этой мелочи:

Я борюсь с той же проблемой, и, кажется, все работает для меня тоже. Однако я бы порекомендовал быть очень осторожным во время выгрузки / выхода, поскольку, если вы используете цикл обработки событий из другого приложения и этот цикл обработки событий останавливается до выгрузки вашей библиотеки, то при попытке закрытия могут произойти всевозможные ошибки. () сокеты и удалить объекты QObject.

1
ответ дан James 29 November 2019 в 00:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: