crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Постоянно течет память при исполнении скрипта
igor_bogomolov
  опции профиля:
сообщение 6.9.2010, 17:34
Сообщение #1


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Непрерывно течет память при исполнении скрипта. Кто сталкивался с подобным? Может я что то не правильно делаю?
За пример можно взять следующий код

bool Param::scriptEval()
{
    QString sFunction = QString(QLatin1String("function vparam(a,b,c,d,e) { return (e<<16) | a | b | c | d; }"));

    QScriptValue sv = scriptEngine->evaluate(sFunction);
    if (scriptEngine->hasUncaughtException()) {
        qDebug() << tr("Script for param '%1' error: '%2' for '%3'")
                   .arg(m_sName).arg(sv.toString()).arg(sFunction);
        return false;
    }

    QScriptValueList svlArgs;
    svlArgs << 0 << 0 << 0<< 0 << 1;

    QScriptValue fnObj = scriptEngine->globalObject().property(QLatin1String("vparam"));
    QScriptValue fnRes = fnObj.call(QScriptValue(), svlArgs);

    QString sResult = fnRes.toString();
    if (sResult.isEmpty()) {
        qDebug() << tr("Script for param '%1' returns NULL value string: %2")
                .arg(m_sName).arg(sFunction);
        return false;
    }

    qDebug() << sResult.toInt();

    return true;
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 6.9.2010, 17:36
Сообщение #2


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


багтрекер троллей смотрел?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 6.9.2010, 18:51
Сообщение #3


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Смотрел, конечно. Есть там такой баг http://bugreports.qt.nokia.com/browse/QTBUG-6426

Просто предполагаю, что я не правильно что то делаю. Не один же я скриптами пользуюсь, но не у нас ни на прогорге подобных жалоб не нашёл. К тому же стандартный пример context2d работает нормально. Там правда хитро как то, да и для моей задачи вреде таких сложностей и не нужно. Остальные стандартные примеры QtScript так же подтекают.

collectGarbage не помогает
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 6.9.2010, 19:43
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


igor_bogomolov, а с какой строчки кода именно начинает появляться проблема ? (можно определить половинным заремариванием функции)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 6.9.2010, 20:38
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


igor_bogomolov, проверь у себя этот код:
int main( int argc, char **argv )
{
    QCoreApplication app1( argc, argv );

    for( int i = 0; i < 100; ++i )
    {
        QScriptEngine scriptEngine;

        QString sFunction = QString( QLatin1String( "function vparam(a,b,c,d,e) { return (e<<16) | a | b | c | d; }" ) );
        QScriptValue sv = scriptEngine.evaluate( sFunction );
        if( scriptEngine.hasUncaughtException() )
        {
            qDebug() << "Script error";
            return 1;
        }

        QScriptValueList svlArgs;
        svlArgs << 0 << 0 << 0 << 0 << 1;

        QScriptValue fnObj = scriptEngine.globalObject().property( QLatin1String( "vparam" ) );
        QScriptValue fnRes = fnObj.call( QScriptValue(), svlArgs );

        QString sResult = fnRes.toString();
        if( sResult.isEmpty() )
        {
            qDebug() << "Script error";
            return 2;
        }

        qDebug() << sResult.toInt();
    }
    
    return 0;
}


Судя по выводу valgrind у меня ничего не течет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 6.9.2010, 20:42
Сообщение #6


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Алексей1153 @ 6.9.2010, 20:43) *
а с какой строчки кода именно начинает появляться проблема ?

QScriptValue sv = scriptEngine->evaluate(sFunction);



BRE, спасибо, сейчас попробую.
А какоя у вас версия Qt?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 6.9.2010, 20:45
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(igor_bogomolov @ 6.9.2010, 21:42) *
BRE, спасибо, сейчас попробую.
А какоя у вас версия Qt?

$ qmake-qt4 --version
QMake version 2.01a
Using Qt version 4.6.3 in /usr/lib64
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 6.9.2010, 22:07
Сообщение #8


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Переделал немного таким образом
Раскрывающийся текст
#include <QtGui/QApplication>
#include <QtGui/QPushButton>
#include <QtCore/QDebug>
#include <QtScript/QScriptEngine>

class Test : public QObject
{
    Q_OBJECT
public slots:
    void evaluate() {
        for (int i=0; i!=1000;++i) {
            QString sFunction = QString( QLatin1String( "function vparam(a,b,c,d,e) { return (e<<16) | a | b | c | d; }" ) );
            QScriptValue sv = scriptEngine.evaluate( sFunction );
            if( scriptEngine.hasUncaughtException() )
            {
                qDebug() << "Script error";
                return;
            }

            QScriptValueList svlArgs;
            svlArgs << 0 << 0 << 0 << 0 << 1;

            QScriptValue fnObj = scriptEngine.globalObject().property( QLatin1String( "vparam" ) );
            QScriptValue fnRes = fnObj.call( QScriptValue(), svlArgs );

            QString sResult = fnRes.toString();
            if( sResult.isEmpty() )
            {
                qDebug() << "Script error";
                return;
            }

            qDebug() << sResult.toInt();
        }
    }
private:
    QScriptEngine scriptEngine;
};

#include "main.moc"

int main( int argc, char **argv )
{
    QApplication app( argc, argv );
    QPushButton button("text");

    Test test;

    QObject::connect(&button, SIGNAL(clicked()), &test, SLOT(evaluate()));

    button.show();
    return app.exec();
}

Valgrind можно сказать спокоен
"вывод valgrind"
Цитата
==13956== LEAK SUMMARY:
==13956== definitely lost: 124 bytes in 1 blocks
==13956== indirectly lost: 0 bytes in 0 blocks
==13956== possibly lost: 37,731 bytes in 530 blocks
==13956== still reachable: 135,512 bytes in 1,259 blocks
==13956== suppressed: 0 bytes in 0 blocks

Но в диспетчере задач, если нажимать на кнопочку, память постоянно растёт.

Я читал ваш комментарий по поводу диспетчера задач
Цитата
Память растет, потому что процесс запрашивает ее у ОС для своего хипа (кучи), но после освобождения памяти в хипе она не обязательно отдается системе обратно, а продолжает использоваться для аллокации внутри процесса. Поэтому, по диспетчеру и не видно ее освобождение.
В общем, диспетчер плохой инструмент для отлова утечек памяти внутри процесса.


Возможно диспетчер и плохой инструмент. Но память растёт непрерывно. За несколько дней начинает превышать 500 МБ и "планировщик" эту программу прибивает. Заказчик не доволен, т.к. программа должна работать непрерывно.

Возможно утечки есть и в другом месте. Сбивает то, что если я комментирую scriptEngine->evaluate утечки прекращаются.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 6.9.2010, 22:21
Сообщение #9


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


igor_bogomolov, как "быстрый костыль" можно попробовать засунуть сиё в отдельный процесс (если логика приложения позволяет).

А ещё - может быть, есть какой-нибудь метод для очистки памяти именно в объекте scriptEngine - его вызывать периодически.

В конце концов, как костыль сойдёт, наверное, периодическое пересоздание объекта scriptEngine через new (со всеми синхронизациями, естественно, если это нужно)

По крайней мере, это всё можно попробовать для убедиться, что дело именно в этом месте

Сообщение отредактировал Алексей1153 - 6.9.2010, 22:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 6.9.2010, 22:21
Сообщение #10


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


==13956== definitely lost: 124 bytes in 1 blocks <--
==13956== indirectly lost: 0 bytes in 0 blocks
==13956== possibly lost: 37,731 bytes in 530 blocks <--

и это спокоен? запусти с флагом --leak-check=full
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.12.2024, 7:23