Каталог решений - Странное потребление места на диске С

Странное потребление места на диске С

Странное потребление места на диске С

В наличии

Решение проблемы постоянного роста папки %AppData%/Local/Temp.

Категория:

Описание

Первым делом смотрим виновника в мониторе ресурсов:

Видим что им является один из процессов rphost с id 8484. (Remote Process HOST)

Далее, смотрим все сеансы этого рабочего процесса, где-то в последних столбцах таблицы ищем потребление диска:

Видим 6 сеансов на этом процессе:

Ага, вот и наш ненасытный сеанс, открытый фоновым заданием под пользователем Adm в 9:57. В колонке "Запись (Текущая)" значение достигло 138 гб! (пред. скрин). Кстати, с этого же времени висит ещё одно. Может они связаны.

Далее идем в консоль заданий и ищем что его породило:

Смотрим код первого:

К сожалению по заданному пути никакого скрипта не было.
И оно, даже не смотря на блок попытки, просто зависало с ошибкой:

Ок, не наш случай. Добавим проверку на существование файла и идём дальше. Код второго регламентного:

Здесь уже интересней. При достаточно большом размере выбираемых данных до второй точки останова выполнение никогда не дойдет.

Когда в запросе выбирается реквизит типа хранилище значений с бинарными данными (поле ФайлДанных) — тогда в результирующую выборку попадает весь размер всех файлов одновременно!

В нашем случае это вызывает ошибку нехватки места на диске:

При выполнении метода Выполнить() данные запроса могут сбрасываться на диск, и вот почему:

http://its.1c.ru/db/v8std#content:-2145782922:1

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

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

2. При потенциально неограниченных выборках данных из ИБ следует получать данные из базы порциями фиксированного размера. 
Например, неправильно:

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";

// Выгрузка всего справочника в таблицу значений 
Номенклатура = Запрос.Выполнить().Выгрузить(); 
Для каждого ПозицияНоменклатуры Из Номенклатура Цикл
// Обработка элемента справочника 
// …
КонецЦикла;

поскольку весь результат запроса сразу помещается в память, в таблицу значений.
Также неправильно:

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура";

РезультатЗапроса = Запрос.Выполнить();
// Обход результата запроса
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Обработка элемента выборки
// …
КонецЦикла;

поскольку и в этом случае при выполнении запроса его результат будет сначала считан в память целиком (*).

* Примечание. Если размер результата запроса превосходит размер имеющейся памяти, то данные будут записаны на диск, а затем считаны оттуда в процессе вызовов Выборка.Следующий().

Правильно ограничивать результат запроса искусственно:

ВсеОбработано = Ложь;
Пока Истина Цикл
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ ПЕРВЫЕ 1000
| Номенклатура.Ссылка,
| Номенклатура.Наименование,
| Номенклатура.ВидНоменклатуры
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| <условие выборки необработанных записей>";

РезультатЗапроса = Запрос.Выполнить();
ВсеОбработано = РезультатЗапроса.Пустой();
Если ВсеОбработано Тогда
Прервать;
КонецЕсли;

// Обход порции результата запроса
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Обработка элемента выборки
// …
КонецЦикла;

КонецЦикла;

Также правильно:

Выборка = Справочники.Номенклатура.Выбрать(…, Отбор);
Пока Выборка.Следующий() Цикл
// Обработка элемента выборки
// …
КонецЦикла;

поскольку в этом случае платформа 1С:Предприятие выполняет курсорный запрос.

Кроме того, число элементов выборки автоматически ограничивает платформа 1С:Предприятие в запросах динамических списков.

Таким образом, переписав код на получение значения хранилища через ключ записи, избавляемся от ошибки нехватки памяти:

 

Вывод: никогда не делайте неограниченную выборку полей типа ХранилищеЗначения, иначе забьёте память и диск!

 

has been added to your cart:
Оформление заказа