Ошибки выделения памяти могут быть вызваны медленным увеличением размера файла страницы
Эта статья содержит обходное решение для ошибок, которые возникают, когда приложения часто выделяют память.
Область действия: Windows 10 — все выпуски
Исходный номер базы знаний: 4055223
Симптомы
В приложениях, которые часто выделяют память, могут возникать случайные ошибки нехватки памяти. Такие ошибки могут привести к другим ошибкам или неожиданному поведению в затронутых приложениях.
Причина
Сбои выделения памяти могут возникать из-за задержек, связанных с увеличением размера файла страницы для поддержки дополнительных требований к памяти в системе. Возможная причина таких сбоев в том, что размер файла страницы настроен как «автоматический». Автоматический размер файла страницы начинается с небольшого файла страницы и при необходимости автоматически увеличивается.
Система ввода-вывода состоит из множества компонентов, включая фильтры файловой системы, файловые системы, фильтры томов, фильтры хранилища и т. д. Конкретные компоненты в данной системе могут привести к вариативности роста файла страницы.
Обходной путь
Чтобы обойти эту проблему, вручную настройте размер файла страницы. Для этого выполните следующие действия:
- Нажмите клавишу с логотипом Windows+ клавишу Pause/Break, чтобы открыть свойства системы.
- Выберите «Дополнительные параметры системы«, а затем выберите «Параметры» в разделе «Производительность» на вкладке «Дополнительно«.
- Перейдите на вкладку «Дополнительно «, а затем выберите «Изменить » в разделе «Виртуальная память».
- Снимите флажок «Автоматически управлять размером файла подкачки для всех дисков».
- Выберите «Пользовательский размер», а затем задайте значения «Начальный размер» и «Максимальный размер» для файла подкачки. Рекомендуется установить начальный размер в 1,5 раза больше объема ОЗУ в системе.
- Нажмите кнопку « ОК», чтобы применить параметры, а затем перезапустите систему. Если вы продолжаете получать сообщения об ошибках нехватки памяти, увеличьте начальный размер файла страницы.
Состояние
Корпорация Майкрософт подтвердила, что это проблема в Windows 10.
Дополнительные сведения
При использовании компилятора Microsoft Visual C++ (cl.exe) могут возникать периодические ошибки сборки, как показано ниже.
- Неустранимая ошибка C1076: ограничение компилятора: достигнут внутренний куч; использование /Zm для указания более высокого ограничения
- Неустранимая ошибка C1083: не удается opentypefile: «file»: message
- Неустранимая ошибка C1090: сбой вызова API PDB, код ошибки «code»: «message»
- Ошибка компилятора C3859: превышен диапазон виртуальной памяти для PCH; Выполните повторную компиляцию с параметром командной строки -ZmXXX или более поздней версии.
Дополнительные сведения об ошибках компилятора Visual C++ и способах их устранения см. в разделе о проблемах и рекомендациях предварительно скомпилированного заголовка (PCH).
Обратная связь
Были ли сведения на этой странице полезными?
Ошибки страницы физической памяти в секунду что это
← →
DVM © ( 2007-05-01 13:42 ) [0]
Что это такое? Как понимать его показания? В справке не описано.
Это нормально, когда у программы он растет со скоростью 2-3 тыс единиц в секунду?
← →
homm © ( 2007-05-01 14:42 ) [1]
> Что это такое? Как понимать его показания?
Да не паникуй ты так. Это количество страниц, к котрым онадобился доступ когда их не было в оперативной памяти. А если еще точнее, то количество страниц, к котрым онадобился доступ когда их не было в рабочем наборе приложения, что не значит что их не было в оперативе.
> Это нормально, когда у программы он растет со скоростью
> 2-3 тыс единиц в секунду?
Нет 🙂 Пора идти в магазин за оперативой 🙂
← →
Eraser © ( 2007-05-01 14:42 ) [2]
> [0] DVM © (01.05.07 13:42)
> Что это такое?
это ошибка доступа к странице памяти, при её возникновении системы выгружает нужную страницу из файла подкачки в ОЗУ.
> Это нормально, когда у программы он растет со скоростью
> 2-3 тыс единиц в секунду?
не очень (хотя тут нужно смотреть конкретную ситуацию), нужно побольше ОЗУ.
← →
homm © ( 2007-05-01 15:05 ) [3]
> Это нормально, когда у программы он растет со скоростью
> 2-3 тыс единиц в секунду?
Я счас подергал окошко оперы за края, погонял апатчь, до 5 тышь в секунду доходило. Вот же уродский оптимайзер памяти у винды 🙁 Так что пара тысячь в секунду — вполне нормально.
← →
DVM © ( 2007-05-01 15:35 ) [4]
Я вот попытался локализовать в своей программе место, которое более всего увеличивает счетчик — оказалось это место в FastDIB. А именно:
procedure FastDIB2Bitmap(Src:TFastDIB;Dst:TBitmap);
begin
if Src.Handle<>0 then
begin
Dst.Handle:=Src.Handle;
// bitmaps can be selected for only one device context at a time
if(Src.hDC<>0)and Src.FreeDC then DeleteDC(Src.hDC);
if(Src.hPen<>0)then DeleteObject(Src.hPen);
if(Src.hFont<>0)then DeleteObject(Src.hFont);
if(Src.hBrush<>0)then DeleteObject(Src.hBrush);
Src.hDC:=0;
Src.FreeDC:=False;
Src.FreeBits:=False;
Src.FreeHandle:=False;
end;
end;
Вот такие преобразования моя программа делает до 200 в секунду.
Если я комментирую преобразование, то счетчик не растет практически.
Памяти 100% достаточно. Ее количество не влияет на этот счетчик. 2Гб ее.
← →
Eraser © ( 2007-05-01 16:40 ) [5]
ну если это не дает лишней нагрузки на CPU — можно смело забить, если нагрузку дает — исключить вызов FastDIB2Bitmap.
← →
antonn © ( 2007-05-01 16:43 ) [6]
щас может тупой вопрос задам:)
А так — procedure FastDIB2Bitmap(Src:TFastDIB; var Dst:TBitmap);
?
← →
DVM © ( 2007-05-01 17:13 ) [7]
> ну если это не дает лишней нагрузки на CPU
Не нагрузки не дает абсолютно. Память не растет, никакие ресурсы не уменьшаются.
> щас может тупой вопрос задам:)
> А так — procedure FastDIB2Bitmap(Src:TFastDIB; var Dst:TBitmap);
>
> ?
Все то же самое.
← →
Eraser © ( 2007-05-01 17:28 ) [8]
> [6] antonn © (01.05.07 16:43)
в Делфи идентификатор объекта является указателем на объект )
← →
antonn © ( 2007-05-01 18:09 ) [9]
> в Делфи идентификатор объекта является указателем на объект
> )
:Р
← →
Sapersky ( 2007-05-01 20:51 ) [10]
Я вот попытался локализовать в своей программе место, которое более всего увеличивает счетчик — оказалось это место в FastDIB.
По логике, нужно сначала всё освободить, потом присваивать Handle. Возможно, и освобождать необязательно, во всяком случае в примере Bumpmap сделано так:
procedure TBumpForm.SetThumbnail(Image:TImage; Bmp:TFastDIB);
var
Tmp: TFastDIB;
begin
Tmp:=TFastDIB.Create;
Tmp.SetSize(105,105,Bmp.Bpp);
if Tmp.Bpp=8 then
begin
Tmp.Colors^:=Bmp.Colors^;
Tmp.UpdateColors;
end;
Bilinear(Bmp,Tmp);
Tmp.FreeHandle:=False;
Image.Picture.Bitmap.Handle:=Tmp.Handle;
Tmp.Free;
Image.Refresh;
end;
А вообще, откуда надобность выполнять подобное преобразование 200 раз/c? Может лучше выкинуть TBitmap и выполнять все операции с TFastDIB? А то мне сейчас лень смотреть, но подозреваю, что в TBitmap.SetHandle куда больше действий, чем просто присвоение переменной.
Ещё, имейте в виду, что FastGate — это не оригинальный FastLIB. Автор этого модуля уже допускал ляпы при «улучшении» библиотеки, так что аккуратнее с ним (хотя, строго говоря, и «оригинал» не безгрешен).
← →
DVM © ( 2007-05-01 22:03 ) [11]
> А вообще, откуда надобность выполнять подобное преобразование
> 200 раз/c?
Да есть вот задачи. Видеонаблюдение.
> Может лучше выкинуть TBitmap и выполнять все операции с
> TFastDIB?
Так и планирую сделать, но есть свои грабли и очень много вносить изменений. В принципе FastDIB тут прикручен из-за фантастически быстрой SetSize.
> TBitmap.SetHandle куда больше действий, чем просто присвоение
> переменной.
Да, там намного больше действий.
> Sapersky
Не подскажите, как правильно скопировать один TFastDIB в другой. Не Assign(), а именно копирование? У меня вот какая штука:
Во вторичном потоке происходит декодирование JPEG в TFastDIB. Далее этот FastDIB с сообщением высылается в основной поток и там преобразуется в TBitmap, который и отрисовывается при необходимости в основном потоке по WM_PAINT. Так сделано сейчас. Так вот получается, что и основной поток и вторичный на деле же работают с одним и тем же хэндлом одного и того же битмапа по сути. Ведь FastDIB2Bitmap просто присваивает хэндл. И пока первичный поток отрисовывает его на окне вторичный ведь может и поменять его содержимое. Или я неправ? Так можно делать или надо полностью копироваить битмап в основной поток и там работать с ним?
← →
homm © ( 2007-05-01 22:06 ) [12]
Хм, а я кажеться понял почему так много ошибок доступа в этом месте. Потому что по Dst.Handle:=Src.Handle; Dst фактически заново создаеться, под новый битмап выделяеться память. А менеджер памяти в виндовсе имеет такое замечательное свойство, не выделять память физически, а лишь помечать страницы как зарезервированые. А вот когда уже на новый хэндл уже копируеться изображение со старого, идет непосредственное обращение к страницам, и они выделяются физически (в ОП), а счетчик ошибок доступа мотает. Так что эта строчка имхо — большая дыра в производительности. Попробуй как минимум создавать TBitmap как DIB, как максимум, здесь вобще нужно логику программы переделывать.
← →
homm © ( 2007-05-01 22:11 ) [13]
> Так вот получается, что и основной поток и вторичный на
> деле же работают с одним и тем же хэндлом одного и того
> же битмапа по сути.
Скорее всего нет. Как я понимаю невозможно преобразовать DDB в DIB не выделив под него второй хэндл.
← →
DVM © ( 2007-05-01 22:21 ) [14]
> Потому что по Dst.Handle:=Src.Handle; Dst фактически заново
> создаеться, под новый битмап выделяеться память
Да, получается, что так.
> Так что эта строчка имхо — большая дыра в производительности.
Может быть, но это далеко не самая тяжелая операция. Декодирование из JPEG во вторичных потоках занимает в тысячи раз больше времени.
> как максимум, здесь вобще нужно логику программы переделывать.
Я вот попробовал переделать на TFastDIB в основном потоке — проблема с ошибками страницы исчезла.
← →
DVM © ( 2007-05-01 22:25 ) [15]
Возникла другая проблема — как мне правильно передать с сообщением переменную типа TFastDIB из вторичного потока в первичный с сообщением и присвоить полченное в основном потоке значение переменной в первичном потоке. Просто присваиванием очевидно нельзя — возникают сразу утечки GDI ресурсов (вот здесь отличие от TBITMAP).
← →
Sapersky ( 2007-05-02 00:38 ) [16]
Не подскажите, как правильно скопировать один TFastDIB в другой. Не Assign(), а именно копирование?
Dst.MakeCopy(Src, True); // делается SetSize и Move
Или можно (при UseGDI = True) установить размер Dst = Src, потом
Src.Draw(Dst.hDC, 0, 0); // фактически BitBlt
удобно тем, что конвертирует битмапы разных форматов, хотя, как правило, не очень качественно. Впрочем, для этого есть FConvert.pas.
И пока первичный поток отрисовывает его на окне вторичный ведь может и поменять его содержимое. Так можно делать или надо полностью копироваить битмап в основной поток и там работать с ним?
Если вторичный поток не изменяет размер битмапа, т.е. не портит указатель/Handle, то, наверное, можно его спокойно рисовать, в крайнем случае нарисуется половина старого, половина нового. Хотя сам не пробовал, не знаю, как функции GDI отнесутся к тому, что кто-то будет писать в используемую ими область памяти. Можно на всякий случай прицепить к битмапу крит. секцию.
Если изменяет — тогда однозначно нужна или синхронизация, или копирование, или и то, и другое.
Просто присваиванием очевидно нельзя — возникают сразу утечки GDI ресурсов (вот здесь отличие от TBITMAP).
Что такое «присваивание»?
Если Assign — возможно, «аффтар» FastGate с ним напортачил в новой версии, пытаясь добиться того же поведения, что и у TBitmap. В оригинале это поведение довольно специфическое — битмап-источник уничтожается.
В общем, лучше «присваивание» делать как Dst := Src с соответствующей синхронизацией или MakeCopy.
← →
Игорь Шевченко © ( 2007-05-02 10:29 ) [17]
> Вот же уродский оптимайзер памяти у винды
Слону, сам понимаешь, пофиг.
← →
DVM © ( 2007-05-02 13:00 ) [18]
> Sapersky (02.05.07 00:38) [16]
Большое спасибо. Метод TFastDib.MakeCopy() действительно то что нужно.
Счетчики ошибок страницы не растут. Утечек тоже нет. Как обстоят дела с производительностью такого решения выясняю.
100 ошибок страниц диск что это в диспетчер задач (монитор ресурсов)
пытаюсь выяснить проблему, когда при установке игр притормаживает комп, при этом нагрузка на проц и оперативку почти на минимум. Заметил что на мониторе ресурсов написано 100 ошибок страниц (диск) что это значит? 100 ошибок
Голосование за лучший ответ
что показывает прога кристалдискинфо?
https://crystalmark.info/download/index-e.html
serega леоновПрофи (931) 6 лет назад
ничего понять не могу, но пишет что всё хорошо
Дык вы тест не провели.
Cкачай Crystal Disk и посмотри, если переназначенных секторов много то все плохо
serega леоновПрофи (931) 6 лет назад
ничего понять не могу, но пишет что всё хорошо
Ушатов Илья Ученик (168) может просто памяти на диске не хватает
Hard Disk Sentinel Pro 5.01.8557 Final / 5.01.7.8557 beta
https://rsload.net/soft/cleaner-disk/9119-hard-disk-sentinel.html
Hard Disk Sentinel Pro — утилита для мониторинга и контроля состояния жестких дисков. Позволяет определить потенциальные проблемы, снижение производительности дисков и их возможные сбои. Предупреждает пользователя об обнаружении неполадок или превышении температуры. Возможности программы явно не будут лишними, особенно в случае особой ценности хранимых данных при росте объема накопителей. Приложение отслеживает статус жестких дисков, включая показатели температур и параметры S.M.A.R.T. (Self-Monitoring, Analysis and Reporting Technology, технология, встроенная в большинство современных накопителей) для каждого жесткого диска. Также измеряет скорость передачи данных в реальном режиме (этот показатель может быть использован для тестирования или определения заниженной производительности в тех или иных ситуациях).
«100 ошибок страниц»
участок памяти размером 4К был выгружен на диск и ее потребовалось загрузить в физическую память, это НОРМАЛЬНО при использовании виртуальной памяти.
«при установке игр притормаживает комп»
он и должен тормозить диск сам на себя игру ставит конечно все остальные операции будут тормозить.
serega леоновПрофи (931) 6 лет назад
serega леоновПрофи (931) 6 лет назад
ниже b4 скины я кидал чуть выше в комент
serega леонов Профи (931) скрины*
Вот тут ответ на твой вопрос:
https://social.technet.microsoft.com/Forums/ru-RU/0e7cb14d-99b8-48bd-aa2c-00594afa2cad/1084108610851080109010861088?forum=vistaru
Если имеется в виду Page Fault то это не ошибки. Это просто значит что запрошеная страница (участок памяти размером 4К) была выгружена на диск и ее потребовалось загрузить в физическую память. Это совершенно нормальное явление в любых ОС с виртуальной памятью.
Черезмерное количество таких явлений однако может привести к снижению производительности и свидетельствует о недостатке физической памяти.
Сотни страниц — это кстати пустяки.
Какое допустимое количество ошибок страницы физической памяти?
Есть небольшой сервер под управлением Windows Server 2016.
После замены планки памяти наблюдаю в мониторе ресурсов много «ошибок страницы физической памяти»:
Допустимы ли такие значения, или планка битая и лучше её заменить?
- Вопрос задан более трёх лет назад
- 18164 просмотра
Комментировать
Решения вопроса 1
Это не имеет никакого отношения к повреждению оперативной памяти.
Это часть механизма свопирования — ошибка означает, что при попытке обратиться к памяти выяснилось, что это участок сброшен из оперативной памяти на диск.
Ответ написан более трёх лет назад
Нравится 6 8 комментариев