При разработке на платформе 1С:Предприятие часто возникает ситуация, когда нам необходимо программно создать объект документа для выполнения каких-либо расчетов или проверки условий, но при этом мы не всегда планируем сохранять его в базу данных. У начинающих разработчиков часто возникает вопрос: нужно ли вызывать специальные методы для «уничтожения» этого объекта, чтобы не засорять память или базу данных? Рассмотрим этот процесс детально.
Для начала разберем, что происходит, когда мы выполняем команду СоздатьДокумент(). В этот момент платформа выделяет участок оперативной памяти для хранения структуры этого объекта. В этой структуре инициализируются реквизиты значениями по умолчанию, создаются пустые табличные части.
Важно понимать: до того момента, пока вы не вызвали метод Записать(), этого документа физически не существует в базе данных (в таблицах SQL или файловой СУБД). Следовательно, если мы решим «отменить» его создание, нам не нужно использовать метод Удалить(), так как этот метод предназначен для удаления уже существующих записей из базы данных. Если вызвать Удалить() для объекта, который еще не был записан, система либо выдаст ошибку, либо ничего не сделает, так как ссылки (UUID) в базе еще нет.
Проанализируем, как платформа 1С понимает, что объект больше не нужен. В 1С используется механизм подсчета ссылок. Работает он следующим образом:
СоздатьДокумент() переменной, счетчик ссылок на этот объект становится равным 1.Рассмотрим пример кода:
Процедура СоздатьЕслиНужно(УсловиеЗаписи)
НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДок.Дата = ТекущаяДата();
// Проводим какие-то вычисления
Если УсловиеЗаписи Тогда
НовыйДок.Записать();
Сообщить("Документ сохранен");
Иначе
// Нужно ли здесь что-то писать?
// Нет, как только процедура закончится, переменная НовыйДок исчезнет,
// и объект будет удален из памяти автоматически.
Сообщить("Условие не выполнено, документ не создан");
КонецЕсли;
КонецПроцедуры
Выясним, в каких случаях всё же стоит явно указывать системе, что объект нам больше не нужен. Это актуально, если вы работаете в рамках длительных циклов или в глобальном контексте. Если вы создаете тысячи объектов внутри одного цикла и не обнуляете переменную, память может начать стремительно расти, так как счетчик ссылок не обнулится до конца работы всего цикла.
Посмотрим на правильную организацию цикла:
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
НовыйДок = Документы.ВыгрузкаРеализации.СоздатьДокумент();
// Заполняем данные
// ...
Если НужноЗаписывать(СтрокаДанных) Тогда
НовыйДок.Записать();
КонецЕсли;
// Явно освобождаем ссылку в каждой итерации цикла
НовыйДок = Неопределено;
КонецЦикла;
Присваивание НовыйДок = Неопределено принудительно обнуляет счетчик ссылок на текущий объект документа в каждой итерации, позволяя платформе переиспользовать память, не дожидаясь завершения всей обработки. Это критически важно для серверных вызовов, где ресурсы памяти ограничены общим пулом процессов rphost.
Проанализируем ситуацию с внешними объектами, которую упоминали участники обсуждения. В отличие от внутренних объектов 1С, COM-объекты (например, при интеграции с Excel или Word) ведут себя иначе.
Если вы просто напишете ExcelОбъект = Неопределено, ссылка в 1С пропадет, но в диспетчере задач Windows процесс excel.exe может остаться висеть. Это происходит потому, что внешний процесс ожидает явной команды на закрытие. Поэтому при работе с COM-объектами всегда придерживайтесь правила:
Application.Quit()).Неопределено.Разберем еще один нюанс — циклические ссылки. Если вы создали документ и поместили ссылку на него, например, в структуру, которую затем сохранили в реквизит самого документа, возникает замкнутый круг. Сборщик мусора может не сразу справиться с такой ситуацией. В сложных алгоритмах с использованием структур, таблиц значений и соответствий, где объекты ссылаются друг на друга, явное обнуление переменных (Объект = Неопределено) является хорошим тоном и страховкой от утечек памяти.
Стоит отметить, что метод СоздатьДокумент() абсолютно «безопасен» для производительности базы данных. Он не открывает транзакцию и не накладывает блокировки на таблицы СУБД. Нагрузка идет исключительно на оперативную память клиента (или сервера, в зависимости от того, где выполняется код).
Пока вы не вызвали Записать(), другие пользователи даже не узнают о том, что вы что-то «создавали». Поэтому «отменять» создание документа какими-то сложными методами не требуется. Ваша главная задача — просто не оставлять ссылок на этот объект в переменных, чтобы память была своевременно очищена.
Подводя итог, можно сформулировать следующие правила работы с программно созданными объектами в 1С:
Удалить() для объектов, которые не были записаны методом Записать().Неопределено: если работаете в длинных циклах с большим количеством создаваемых объектов.Следование этим простым правилам сделает ваш код чище, а работу системы — стабильнее.