Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Утечка памяти в платформе?
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.2 > Программирование обычных форм 1С 8.2 и не интерфейсной логики
Maximus314
Доброго Вам времени суток!

Столкнулся со странным поведением платформы на казалось бы элементарном алгоритме.

Написал обработку перепроведения базы с определенной спецификой и вполне благополучно ее использовал, но когда количество документов в базе превысило некое критическое количество обработка начала приводить к аварийному завершению работы 1С с выдачей сообщения о нехватке памяти.

Попытка найти ошибку в алгоритме привела к постепенному "выбрасыванию" фрагментов кода пока от алгоритма не остался по сути цикл получения документов и самое странное - проблема нехватки памяти не исчезла.

Вот пример кода, который отрабатывает за 9 секунд и при этом объем занятой памяти процессом 1C8.exe находится на уровне 36Мб
    Выборка = Документы.РасходнаяНакладная.Выбрать();
    Кво = 0;
    Пока Выборка.Следующий() Цикл
        Док = Выборка.ПолучитьОбъект();
        Кво=Кво+1;
        Если Кво>10000 Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла;

Однако стоит добавить обращение через ссылку, как ситуация кардинальным образом меняется - обработка длится 32 секунды и процесс выделяет 145Мб памяти:

    Выборка = Документы.РасходнаяНакладная.Выбрать();
    Кво = 0;
    Пока Выборка.Следующий() Цикл
        Док = Выборка.Ссылка.ПолучитьОбъект();
        Кво=Кво+1;
        Если Кво>10000 Тогда
            Прервать;
        КонецЕсли;
    КонецЦикла;

Получается, что если получать объект непосредственно из выборки, то все "летает" и работает вполне корректно.

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

Заранее благодарю за помощь в решении данного вопроса!

PS: Версия платформы 8.2.17.153

Vofka
Попробуйте после выполнения действий обнулять переменную Док:
    Выборка = Документы.РасходнаяНакладная.Выбрать();
    Кво = 0;
    Пока Выборка.Следующий() Цикл
        Док = Выборка.Ссылка.ПолучитьОбъект();
        Кво=Кво+1;
        Если Кво>10000 Тогда
            Прервать;
        КонецЕсли;
        Док = Неопределено;
    КонецЦикла;
logist
А в чем вопрос то? Вы получили ссылки в выборке, зачем получать их еще раз?
Acid
Цитата(Maximus314 @ 23.01.13, 22:45) необходимо зарегистрироваться для просмотра ссылки
система начинает задумываться и выделять память, которую не освобождает даже после закрытия формы обработки.

Заранее благодарю за помощь в решении данного вопроса!

Обратитесь в 1С! smile.gif
pumbaE
необходимо зарегистрироваться для просмотра ссылки
Acid
Цитата(pumbaE @ 24.01.13, 12:28) необходимо зарегистрироваться для просмотра ссылки
необходимо зарегистрироваться для просмотра ссылки

на самом деле это "особенность" платформы 1С. Объектная модель в нормальных ООП-языках через точку отрабатывает как надо.
Поэтому я бы дополнил название статьи smile.gif
Vofka
Цитата(Acid @ 24.01.13, 13:28) необходимо зарегистрироваться для просмотра ссылки
Объектная модель в нормальных ООП-языках через точку отрабатывает как надо.

В других языках объектная модель <> объектной модели 1С. Объектная модель в 1С во многом рассчитана на работу с базой данных и через точку во многих случаях система неявно начинает работать с базой. И сделано это для того, чтобы облегчить нам работу и что бы мы не думали о низкоуровневых (если можно это так назвать) штучках-дрючках.
Acid
поэтому 1С не корректно называть объектной из уважения к ООП.
Псевдо-объектная модель, скорее.

И все равно приходится работать с
Цитата(Vofka @ 24.01.13, 13:34) необходимо зарегистрироваться для просмотра ссылки
что бы мы не думали о низкоуровневых (если можно это так назвать) штучках-дрючках
штучками-дрючками при разработке, например, веб-сервисов. smile.gif
Vofka
Цитата(Acid @ 24.01.13, 13:53) необходимо зарегистрироваться для просмотра ссылки
поэтому 1С не корректно называть объектной из уважения к ООП.
Псевдо-объектная модель, скорее.

То что называется "Объектная модель в 1С" - это работа с 1С-ными объектами, вот и все. Где-то у нас поднимались споры насчет того, что 1С это объектно-ориентированная "вещь". Я и тогда говорил и сейчас говорю, что 1С - это предметно-ориентировання вещь. Ладно, думаю не стоит разводить в этой теме холивар по этому поводу smile.gif

Цитата(Acid @ 24.01.13, 13:53) необходимо зарегистрироваться для просмотра ссылки
И все равно приходится работать с штучками-дрючками при разработке, например, веб-сервисов. smile.gif

Ну я ж и не говорил, что во всем так, я говорил, что "во многом". Вот веб-сервисы ко "многим" не относятся smile.gif . Благодаря тому, что разработчики платформы "скрыли" многие вещи от программистов, чем упростили нам работу, уровень вхождения в 1С очень большой, а качество работы очень многих "специалистов" просто обнять и плакать оставляет желать лучшего.
vadim007
Извиняюсь, что немного не в тему - тут речь о восьмерке.
У меня было подобное, но на семерке.
"Специалист", ранее обслуживающий контору, в доке ВозвратнаяНакладная написал след. код:
Опер = ДокПродажи.Операция;
Опер.ВыбратьПроводки();
Пока Опер.ПолучитьПроводку()=1 Цикл
   ...
КонецЦикла;

Все работало ничего, но однажды создали документ на более чем 3000 позиций. И при проведении такого возврата 1С вываливалась с сообщением об ошибке.
Сразу не въехал в проблему, но через два дня проб и ошибок пришел к следующему алгоритму:
       Опер = СоздатьОбъект("Операция");
    Если Опер.НайтиОперацию(ДокПродажи) = 0 Тогда
        Текст = Шаблон("У документа '[ДокПродажи]' операция не найдена!");
        Сообщить(Текст, "!!!");
        Возврат;
    КонецЕсли;
    //! Опер = ДокПродажи.Операция;
    Опер.ВыбратьПроводки();
    Пока Опер.ПолучитьПроводку()=1 Цикл
                ...
    КонецЦикла;

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.