Непрерывно течет память при исполнении скрипта. Кто сталкивался с подобным? Может я что то не правильно делаю?
За пример можно взять следующий код
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;
багтрекер троллей смотрел?
Смотрел, конечно. Есть там такой баг http://bugreports.qt.nokia.com/browse/QTBUG-6426
Просто предполагаю, что я не правильно что то делаю. Не один же я скриптами пользуюсь, но не у нас ни на прогорге подобных жалоб не нашёл. К тому же стандартный пример context2d работает нормально. Там правда хитро как то, да и для моей задачи вреде таких сложностей и не нужно. Остальные стандартные примеры QtScript так же подтекают.
collectGarbage не помогает
igor_bogomolov, а с какой строчки кода именно начинает появляться проблема ? (можно определить половинным заремариванием функции)
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;
}
QScriptValue sv = scriptEngine->evaluate(sFunction);
Переделал немного таким образом
#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();
}
igor_bogomolov, как "быстрый костыль" можно попробовать засунуть сиё в отдельный процесс (если логика приложения позволяет).
А ещё - может быть, есть какой-нибудь метод для очистки памяти именно в объекте scriptEngine - его вызывать периодически.
В конце концов, как костыль сойдёт, наверное, периодическое пересоздание объекта scriptEngine через new (со всеми синхронизациями, естественно, если это нужно)
По крайней мере, это всё можно попробовать для убедиться, что дело именно в этом месте
==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 <--
да это утечки Qt, тоже их замечал.
Не уверен что поможет, но можно перед вызовом QScriptEngine::evaluate() делать pushContext (), а после popContext(). Насколько я понимаю данные имеют локальный характер, и возможно они увеличивают GlobalObject.
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)