Утечка памяти при синхронизации со стороны 1С (7.7)
Приветствую!
Пользуясь стандартными примерами синхронизации со стороны 1С написал код который осуществляет простую задачу - переносит в Террасофт счета, создавая их или же обновляя существующие.
Вот ключевые фрагменты кода:
refInvoice = CreateObject("Document.Счет");
endif;
refInvoice.SelectDocuments();
while (refInvoice.GetDocument() > 0) do
if ((EmptyValue(refInvoice.DocNum) = 1) or (refInvoice.DocDate > FinishDate) or (refInvoice.DocDate StartDate)) then
continue;
endif;
InvoiceID = GetInvoiceTS(refInvoice);
enddo;
function GetInvoiceTS(refInvoice)
if (EmptyValue(dsInvoice) = 1) then
dsInvoice = GetdsInvoice();
endif;
СlearDSFilters(dsInvoice);
ApplyDSFirstLevelFilter(dsInvoice, "InvoiceNumber", TrimAll(refInvoice.DocNum), TRUE);
dsInvoice.Open();
if (dsInvoice.IsEOF = TRUE)
then
dsInvoice.Append();
InvoiceID = TS.GenGUID();
fldName = dsInvoice.DataFields("ID");
fldName.Value = InvoiceID;
else
dsInvoice.Edit();
InvoiceID = dsInvoice.Values("ID");
endif;
fldNumber = dsInvoice.DataFields("InvoiceNumber");
fldNumber.Value = refInvoice.DocNum;
dsInvoice.Post();
dsInvoice.Close();
dsInvoice = 0;
return InvoiceID;
endfunction
function GetdsInvoice()
dsInvoice = Services.GetNewItemByUSI("ds_Invoice");
dsInvoice.FetchRecordsCount = -1;
return dsInvoice;
endfunction
Код работает, но при длительном выполнении (если не ограничивать массив счетов например по дате) выполнение прерывается с ошибкой "Out of memory".
И действительно процесс 1cv7l.exe занимает в памяти изначально около 60Мб, но после запуска синхронизации стремительно растет и перевалив за 700Мб прерывается.
Другими словами количество выделяемой памяти постоянно увеличивается, примерно на 500Кб для каждого счета.
Как показали эксперименты с комментированием команд, ключевыми для повторения ошибки являются dsInvoice.Append() или dsInvoice.Edit() функции GetInvoiceTS. То есть без них выделяемая память не растет.
Кто-нибудь знает как с этим бороться?
Спасибо.
Нравится
Попробуйте следующее:
- судя по коду, dsInvoice у Вас глобальная переменная, и в начале функции GetInvoiceTS Вы проверяет, инициализирована ли она. В этом случае не стоит в конце функции обнулять эту переменную (dsInvoice = 0), так как для следующего вызова опять создастся датасет, и это ведет к потери памяти.
- так как при поиске счета Вас интересует максимум одна запись, в функции GetdsInvoice достаточно установить FetchRecordsCount = 1.
--------------------------------------------
Лабитек
Центр разработки приложений
Бегло просмотрел код. Кажется причина в GetNewItemByUSI и постоянном создании сервисов датасета. Может использовать GetSingleItemByUSI или создать набор данных один раз ?
Действительно, оказалось достаточно убрать dsInvoice = 0; и утечки памяти прекратились.
Еще раз огромное спасибо.