LimeReport Forum

General Category | Основное => Discussion | Обсуждение => Topic started by: DrGluck on February 15, 2016, 03:23:57 PM

Title: Bug: утечка памяти при удалении ReportEngine
Post by: DrGluck on February 15, 2016, 03:23:57 PM
Сценарий прежний: создаётся класс, который создаёт экземпляр ReportEngine и модель. Модель может быть owned или нет, всё равно. Вызываем превью, закрываем, удаляем ReportEngine. После этого регулярно не очищается некоторое количество памяти. На тестовом отчёте в 200 страниц утекает по несколько мегабайт. После пары сотен таких действий получилась картинка (см. аттач).

[вложение удалено администратором]
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: Arin Alex on February 15, 2016, 03:27:46 PM
Спасибо. Очень полезная информация. Обязательно гляну.   
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: Arin Alex on February 15, 2016, 04:47:06 PM
А что за утилита на скриншоте ?
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: DrGluck on February 15, 2016, 05:00:09 PM
Process Hacker, но это не принципиально, можно взять Process Explorer от Руссиновича.
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: DrGluck on February 15, 2016, 05:52:53 PM
Ну, собственно, вот:
Code: [Select]
for ( int i = 0; i < 10; i++)
{
    _limeInstance()->previewReport();
}
После previewReport память вообще не очищается, за 20 вызовов доходит до 1ГБ.

[вложение удалено администратором]
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: Arin Alex on February 16, 2016, 10:34:12 AM
Проблема несвоевременного удаления объектов в previewReport(), имеет место быть и исправляется через изменение деструктора PreviewReportWindow

PreviewReportWindow::~PreviewReportWindow()
{
    if (m_ownedSettings)
        delete m_settings;
    if (m_previewPage)
        delete m_previewPage;
    delete ui;
}

Дальнейшие тесты выдают (см. аттач.)
Тест проводился на следующем коде:

for (int i=0;i<30;++i){
    LimeReport::ReportEngine* re = new LimeReport::ReportEngine();
   
    QSqlQueryModel* customersModel = new QSqlQueryModel();
    customersModel->setQuery("select * from customers", m_db);
    re->dataManager()->addModel("external_customers_data",customersModel,true);
    QSqlQueryModel* ordersModel = new QSqlQueryModel();
    ordersModel->setQuery("Select * from orders",m_db);
    re->dataManager()->addModel("external_orders_data",ordersModel,true);
   
    re->loadFromFile(fileName);
    re->previewReport();
    delete re;
}
Роста потребления не наблюдается.

[вложение удалено администратором]
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: DrGluck on February 16, 2016, 11:15:54 AM
Сейчас попробуем. Надеюсь в новой версии это уже будет исправлено в самой библиотеке.
Но что делать с падением при попытке удаления открытого отчёта?
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: Arin Alex on February 16, 2016, 11:23:28 AM
Это дело мы тоже проверим, возможно, это как раз связано с выше приведенной ошибкой. 
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: DrGluck on February 16, 2016, 11:30:17 AM
И, этсамое, а зачем проверять m_settings и m_previewPag? delete и так прекрасно справляется.
Я понимаю, что это привычка, но уж лучше тогда завести привычку сразу писать
delete _settings;
_settings = nullptr;
даже если кажется, что это не имеет смысла. А то были случаи, когда потом добавился вызов какой-нибудь функции, которая юзала указатель.
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: DrGluck on February 16, 2016, 01:11:54 PM
Подтверждаю, не течёт. Во-всяком случае в тестовой программе. Сейчас попробую боевую, там отчёт по 300-400 метров жрёт.
Title: Re: Bug: утечка памяти при удалении ReportEngine
Post by: DrGluck on February 17, 2016, 02:51:26 PM
Дополнение: пустой отчёт, модель не подключена, добавляем Report Header с текстом и запускаем превью 100-200 раз.
У меня память приложения постепенно увеличивается примерно на 5-6 метров. Это, вроде не много, но на отчёте в 500 мегабайт столько утекает иногда на одном запуске.
Проверялось методом "создал репорт, вызвал превью, дождался закрытия, удалил репорт, го то 1".