Перейти к содержанию

Отсутствует удаление данных из временного хранилища после использования (MissingTempStorageDeletion)

Тип Поддерживаются
языки
Важность Включена
по умолчанию
Время на
исправление (мин)
Теги
Дефект кода BSL
OS
Критичный Нет 3 standard
performance
badpractice

Описание диагностики

Диагностика сейчас отслеживает все вызовы ПолучитьИзВременногоХранилища, для которых нет соответствующего вызова УдалитьИзВременногоХранилища - в рамках одного метода!

Разработчики нередко нарушают правила работы с объектами во временном хранилище, забывая, что хранение данных в нем не является бесплатным. Даже в литературе и многочисленных примерах использования встречаются ошибки.

При помещении данных во временное хранилище следует выбрать один из двух вариантов:

  • помещать данные во временное хранилище на время жизни формы, используя уникальный идентификатор формы
  • и очищать это временное хранилище после использования.
  • предварительно выполнять инициализацию временного хранилища и переиспользовать его.

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

Помните, что при получении на сервере значения из временного хранилища следует учитывать то, что оно получается по ссылке. Эта ссылка указывает на значение, которое хранится в кеше. В течение 20 минут, с момента помещения в хранилище или же с момента последнего обращения, значение сохранится в кеше, а затем записывается на диск и из кеша удаляется. При следующем обращении значение загружается с диска и снова помещается в кеш.

Примеры

1 - Пример правильного кода:

&НаКлиенте
Процедура ПриОбработкеПодобранныхТоваров(Элемент, АдресТоваровВХранилище, СтандартнаяОбработка) Экспорт
    Если АдресТоваровВХранилище = Неопределено Тогда
        Возврат;
    КонецЕсли;
    ПолучитьТоварыИзХранилища(АдресТоваровВХранилище); 
КонецПроцедуры

&НаСервере
Процедура ПолучитьТоварыИзХранилища(АдресТоваровВХранилище)
    ПодобранныеТовары = ПолучитьИзВременногоХранилища(АдресТоваровВХранилище);
    Объект.Товары.Загрузить(ПодобранныеТовары);

    УдалитьИзВременногоХранилища(АдресТоваровДокумента); // очищается временное хранилище для минимизации расхода оперативной памяти
КонецПроцедуры 

2 - Важно учитывать эту рекомендацию при работе с фоновыми заданиями

Неверно: - При каждом выполнении фонового задания его результат помещается во временное хранилище на время жизни формы:

ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения, ПараметрФоновогоЗадания);

  • Если длительная операция выполняется пользователем многократно, пока эта форма открыта, то временные хранилища накапливаются, что вызывает рост потребления памяти.
  • Поэтому для уменьшения расхода оперативной памяти в большинстве случаев рекомендуется очищать временное хранилище сразу после получения результата фонового задания:

Верно:

Настройки = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
УдалитьИзВременногоХранилища(Результат.АдресРезультата);  // Данные во временном хранилище больше не требуются.

  • Если же результат фонового задания требуется сохранять на протяжении нескольких серверных вызовов, то необходимо передавать фиксированный адрес заранее инициализированного временного хранилища:
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ)
        АдресРезультатаФоновогоЗадания = ПоместитьВоВременноеХранилище(Неопределено, УникальныйИдентификатор); // Резервируем адрес временного хранилища
    КонецПроцедуры
    
    &НаСервере
    Функция НачатьПоискНастроекУчетнойЗаписи()
        ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияФункции(УникальныйИдентификатор);
        ПараметрыВыполнения.АдресРезультата = АдресРезультатаФоновогоЗадания; // всегда используем одно и то же временное хранилище
    
        Возврат ДлительныеОперации.ВыполнитьФункцию(ПараметрыВыполнения,
            "Справочники.УчетныеЗаписиЭлектроннойПочты.ОпределитьНастройкиУчетнойЗаписи",
            АдресЭлектроннойПочты, Пароль);
    КонецФункции
    

3 - Или другой пример предварительной инициализации временного хранилища для переиспользования

// в форме документа
&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
    АдресТоваров = ПоместитьВоВременноеХранилище(Неопределено, УникальныйИдентификатор); // Инициализируется реквизит формы
КонецПроцедуры

&НаСервере
Функция ТоварыВоВременномХранилище()
    Возврат ПоместитьВоВременноеХранилище(Товары.Выгрузить(), АдресТоваров);
КонецФункции

// и далее при переиспользовании временного хранилища не требуется удалять значение из временного хранилища:

&НаСервере
Процедура ПолучитьТоварыИзХранилища(АдресТоваровВХранилище)
    ПодобранныеТовары = ПолучитьИзВременногоХранилища(АдресТоваровВХранилище);
    Объект.Товары.Загрузить(ПодобранныеТовары);
КонецПроцедуры

Источники

Сниппеты

Экранирование кода

// BSLLS:MissingTempStorageDeletion-off
// BSLLS:MissingTempStorageDeletion-on

Параметр конфигурационного файла

"MissingTempStorageDeletion": false