При работе с базами конфигурации «Управление торговлей 10.3» и другими решениями на обычных формах пользователи нередко сталкиваются с аварийным завершением программы и сообщением «Недостаточно памяти» в момент интерактивного открытия формы списка регистра накопления (например, Товары организаций). Проблема чаще всего проявляется в файловых базах данных (формат .1cd), объем которых перешагнул отметку в 4–8 гигабайт, при этом стандартная утилита chdbfl.exe ошибок не обнаруживает.
Разберем природу этого сбоя, выясним ключевые причины нехватки памяти и рассмотрим пошаговые методы восстановления стабильной работы программы.
Почему возникает ошибка: аппаратные и архитектурные ограничения
Проанализируем техническую сторону ситуации. Появление ошибки связано с несколькими взаимосвязанными факторами:
Лимит адресного пространства 32-битного процесса. В файловом режиме платформа 1С функционирует в рамках единого 32-битного клиентского приложения. Для такого процесса операционная система выделяет не более 2 ГБ (в редких случаях тонкой настройки — до 3 ГБ) виртуальной памяти независимо от общего объема оперативной памяти на компьютере. Если при формировании списка выделяемый непрерывный блок памяти превышает этот порог, платформа падает с ошибкой.
Ограничение файловой базы на размер отдельной таблицы. В файловой базе данных со стандартным размером страницы 4096 байт максимальный объем одной физической таблицы (или ее индекса) составляет 4 ГБ. В базе объемом 8 ГБ один только регистр Товары организаций с таблицами движений и итогов легко достигает этого предела.
Позиционирование и неиндексированные сортировки. Платформа 1С сохраняет пользовательские настройки формы: сортировки по графам, видимость колонок и позицию курсора. Если в форме списка была включена сортировка по полю, не входящему в состав основного индекса, или курсор остался на последней строке многомиллионной таблицы, СУБД 1С пытается считать и отсортировать огромный массив данных прямо в памяти.
Сбитые или неактуальные итоги регистра остатков. При открытии формы регистра остатков платформа считывает актуальные агрегаты. Если итоги давно не рассчитывались или период итогов отключен, системе приходится рассчитывать виртуальные таблицы остатков динамически с начала ведения учета, что мгновенно переполняет память.
Неоптимальный код в обработчиках отрисовки списка. На обычных формах табличное поле использует события ПриВыводеСтроки и ПриПолученииДанных. Наличие в них тяжелых запросов, получение свойств через цепочки точек (разыменование ссылок) или вывод строковых реквизитов неограниченной длины без кэширования вызывает лавинообразное потребление памяти клиентом.
Способ 1. Сброс пользовательских настроек формы и очистка клиентского кэша
Разберем самое быстрое первичное действие. Если база в целом исправна, но конкретный пользователь сохранил критический отбор или неудачную сортировку, восстановим форму к исходному состоянию:
Запустим программу в режиме «1С:Предприятие» под пользователем с полными правами.
Перейдем в меню «Операции» — «Справочник» — «Пользователи» (либо в список сохраненных настроек) и очистим сохраненные настройки диалогов и форм для проблемного пользователя по регистру Товары организаций.
Закроем 1С и полностью удалим локальный кэш пользователя. Для этого очистим содержимое каталогов:
%LocalAppData%\1C\1Cv8 %AppData%\1C\1Cv8
Способ 2. Актуализация и пересчет итогов регистра накопления
Проанализируем состояние таблиц итогов регистра. Если дата рассчитанных итогов отстает от реального периода документов, восстановим регламентное состояние агрегатов:
Откроем режим «1С:Предприятие».
Перейдем в главное меню: «Операции» — «Управление итогами».
Проверим значение даты, по которую рассчитаны итоги. Если расчет выключен или дата находится в прошлом, установим период расчета на конец следующего или текущего месяца.
Нажмем кнопку «Установить» и выполним полный пересчет итогов. Для поврежденных таблиц выполним процедуру «Пересчитать итоги за весь период» по проблемному регистру.
Способ 3. Переиндексация и сжатие базы через выгрузку и загрузку файла DT
Штатная утилита проверки целостности chdbfl.exe часто не видит логической фрагментации файла .1cd. При интенсивном удалении и перезаписи движений в файле образуются пустые страницы, а индексы сильно фрагментируются. Проведем физическую реструктуризацию:
Откроем базу в режиме «Конфигуратор».
Выберем меню «Администрирование» — «Выгрузить информационную базу» и сформируем файл .dt. Механизм выгрузки читает только фактические данные, исключая фрагменты удаленных записей.
Создадим новую пустую файловую базу данных через стартер 1С.
В новой базе зайдем в Конфигуратор и выберем «Администрирование» — «Загрузить информационную базу», указав созданный ранее файл. При загрузке таблицы файла .1cd и индексы формируются заново в сжатом непрерывном виде.
В исходной или созданной базе выполним процедуру «Администрирование» — «Тестирование и исправление...», включив флаги «Реиндексация таблиц информационной базы» и «Пересчет итогов».
Способ 4. Увеличение размера страницы утилитой cnvdbfl
Если размер таблицы регистра в файловой базе превышает 4 ГБ, а переходить на SQL прямо сейчас нет возможности, снимем ограничение платформы на максимальный размер таблицы. Начиная с платформы 8.3.8 поддерживается конвертация формата файла базы на увеличенный размер внутренней страницы (8192, 16384, 32768 или 65536 байт):
Обязательно создадим резервную копию файла базы данных (1Cv8.1CD).
Завершим все сеансы работы с базой данных.
Запустим командную строку и перейдем в папку исполняемых файлов платформы (обычно C:\Program Files (x86)\1cv8\<номер_релиза>\bin).
Выполним команду конвертации утилитой cnvdbfl.exe, задав размер страницы 8 КБ (8192 байта) или 16 КБ:
cnvdbfl.exe -c -s 8k "D:\Bases\Trade\1Cv8.1CD"
Дождемся окончания процесса. Это увеличит максимально допустимый объем любой внутренней таблицы в базе данных до 8 ГБ (или более при размере страницы 16k), исключив вылеты из-за переполнения внутренней адресации файла.
Способ 5. Доработка формы: жесткий отбор и оптимизация процедур отрисовки
Посмотрим на программную составляющую. Открывать список регистра накопления с миллионами строк без отбора на практике не имеет практического смысла. Чтобы защитить клиентское приложение от сбоев, установим принудительный отбор в модуле формы списка регистра или в точке ее вызова.
Рассмотрим пример установки отбора при открытии формы списка в модуле формы:
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
// Если отбор по периоду или регистратору не установлен, зададим ограничение
Если Не Отбор.Регистратор.Использование И Не Отбор.Период.Использование Тогда
Отбор.Период.Установить(НачалоДня(ТекущаяДата()), КонецДня(ТекущаяДата()), ВидСравнения.ИнтервалВключаяГраницы);
КонецЕсли;
КонецПроцедуры
Также проанализируем обработчики ПриВыводеСтроки и ПриПолученииДанных в модуле формы списка регистра:
Убедимся, что внутри обработчиков отсутствуют прямые запросы к базе данных на каждую строку таблицы.
Проверим, не выводятся ли в колонках реквизиты составного типа или длинные строковые поля неограниченной длины. Если требуется вывод дополнительных данных, получим их пакетным запросом в событии ПриПолученииДанных сразу для всего массива видимых строк и поместим в кэш структуры или соответствия.
Способ 6. Кардинальные решения: клиент-серверный режим и свертка
Если база данных превысила объем 8 ГБ, файловая архитектура исчерпала свой ресурс надежности. Для стабильной эксплуатации крупной информационной базы требуются системные меры:
Перевод на клиент-серверный вариант (SQL). Переход на 64-разрядный сервер «1С:Предприятия» (PostgreSQL, MS SQL Server) полностью снимает ограничения файловой блокировки и изолирует процесс выполнения ресурсоемких выборок на стороне мощного сервера.
Свертка информационной базы. Для конфигурации «Управление торговлей 10.3» стандартной практикой является обрезка базы за прошлые периоды. Свертка сворачивает движения регистра Товары организаций за закрытые годы в единый документ ввода начальных остатков, сокращая размер файла базы данных в несколько раз.