Сталкиваюсь иногда в своем редакторе памяти при сканировании АП другого процесса с регионами памяти доступ к которым очень медленный (порядка 6-14 мб/сек). Причем как правило эти регионы бывают очень крупные (31,8мб и 128мб), и чаще всего встречаются в играх DirectX. Вот недавно заметил такой регион в VisualStudio.NET, в нем он приводил к страшным тормозам при сохранении (проц на 100% загружается при чтении из этого региона, записывать в него нельзя). Один раз даже пришлось снять задачу с нее - начал сохранять файл (9кб) и не смог прекратить. После переустановки системы с VS регион никуда не делся, но с сохранением стало все в порядке. У моих знакомых такие регионы проявлялись из-за сбойных видеокарт ATI, но у меня сейчас NVDIA GeForce2 MX440 довольно нормальная. Этот же регион проявляется и на другой машине. От жесткого диска и сети этот регион вроде не зависит (и то и другое молчит при его сканировании). Его аттрибуты PAGE_READWRITE, MEM_MAPPED. Отчего могут создаваться такие регионы и как их можно вычислить? Если это проекция файла устройства - можно как-нибудь определить имя этого файла ?
Дык имхо это регионы памяти отсутствующие в оперативе и грузящиеся из файла подкачки. В играх естественно их будет больше.
Такого быть не должно - жесктий диск молчит, скорость в 2-3 меньше чем у жеского диска, и потом ЦП грузится на 80%-100%. И за несколько проходов он наверняка должен был бы загрузиться в кэш память.
Почему нельзя, с чем связано? Ты сканируешь когда потоки другого процесса приостановлены? Какой процесс грузит CPU? Имхо, если игра во всю играет, оперативы мало, а ты её ещё сканирушь, то будет выброс одних (измененных, давно-используемых) страниц в своп, подгрузка других (тобой запрашиваемых) страниц из свопа\образа на HDD\CD\NETWORK (кеша этих устройств)
Вот самое интересное в том что несмотря на аттрибуты страниц региона PAGE_READWRITE, запись в его ни к чему не приводит. Содержимое их просто не изменяется. Все потоки сторонних исследуемого процесса приостановленны. При этом нагрузка выделяется на сканирующий поток (который вызывает ReadProcessMemory), в режиме ядра (красные и зеленые линии в ProcessExplorer параллельны). Оперативы больше чем достаточно, при размере региона 31.8 Мегайбайта (который в VStudio) - свободно еще около 200.
У меня NET.VisualStudio.NET , я бы попробовал посмотреть карту памяти в одбг или считать десяток байт (не нулей есс-но) из региона (если в него писать нельзя), потом поиск этой сигнатуры WinHEX'ом по HDD, а вдруг найдешь
Какая может быть взаимосвязь у этой проекции файла (если это вообще проекция) с жестким диском. Ведь при чтении региона жесткий диск никак не реагирует. Для проверки я вырубал подкачку и дожидался пока винт "заснет", и читал весь процесс. Винт так и не проснулся, а скорость по прежнему была около 5-6мб/сек. Да и обычно доступ к страницам не должен вызывать такой нагрузки на ЦП, даже если они проецируются в файл на жестком диске. Скорость чтения на моем винте порядка 33мб/сек. Кстати основной вопрос - можно ли как-нибудь определить имя файла который проецируется в этот регион ? [edited] Было сделано наблюдение с помощью Process Explorer: Размер региона: 0x1FD0000 или 33357824 байт .NET CLR Memory # Total reserved Bytes 33546160 (0x1FFDFB0) байт Разница в 0x2DFB0 ~= 184 KiB, а таких регионов в процессе 6 штук, что впрочем ни о чем не говорит.
Так это наверное Автоматическое управление памятью в .NET, которое видимо сжимает\разжимает\дефрагментирует виртуальную память, мля Ж) придумали ...
Мдя. Надо проверить будет на играх, если конечно удатся обнаружить игру с .NET. Не совсем понятно каким образом CLR умудряется так тормозить обращение к памяти, ведь управляемый код врядли будет иметь премущества по отношению к ReadProcessMemory. Получится что он и вовсе работать будет как BASIC программа на ZX-Spectrum. Надо попробывать написать программу под CLR, может регион в ней проявится. Дык как там насчет проекций файлов драйверов - такое возможно ? И как получить имя спроецированного файла по адресу региона ?
Тоже сталкивался с подобным раньше. И у меня сложилось впечатление, что такое замедление связано с тем, что в данный момент, этот регион памяти активно используется программой. Это конечно ИМХО, но все же думаю стоит попробовать перед чтением засуспендить треад (при необходимости несколько)
DirectX может залочить некоторые физические страницы, что бы DMA использовать - может быть с этим как-то связано? Хотя судя по скорости создаётся впечатление, что при чтении exeption возникает постоянно (непонятно почему). Интересно, а сайс может в эту память писАть?
2alpet: при сохранении региона памяти, вызывающего сильную загузку ЦП, просто нажми Ctrl-D, и посмотри в айсе на стек. повтори эту операцию несколько раз. какой-то код будет встречаться чаще остальных. он и грузит ЦП. ну атрибуты странц не мешает посмотреть...
Я поймал эту точку когда был баг со студией - при загрузке файлов. Место где застревала студия: Код (Text): MSVCR71.dll!memmove+0x1b4 7C342B42 rep movs dword ptr [edi],dword ptr [esi] Поскольку вся нагрузка ложилась на режим ядра можно предположить что прерывания возникали при попытке доступа к странице. Поскольку страница не обьявленна как PAGE_NOCACHE вся задержка видимо выливалась при загрузке линеек - многократное чтение страниц региона производится без задержек. Все никак не соберусь проверить другие .NET приложения на наличие таких регионов. [edited] Регион исчезает после перезагрузки компьютера через hibernate, и появляется после компиляции проекта.
alpet А это не стек ли? При линейном чтении - разрастается, скока тредов - стока и регионов, многократное чтение уже без задержек...
semen Нет, уже ясно что-то некоторый элемент архитектуры памяти .NET. Любое обращение к страницам этого региона дает прерываение, наверное что-то вроде #PAGE_FAULT. Мне сейчас более интересно, как выявлять такие регионы как вредные, помимо замеров времени чтения из них.
alpet Ну так стек если линейно читать - то тоже фолт будет - разрастание стека типа. Вот я и подумал... Тока вот он вниз растет - возможно потому ему и сносит крышу: Код (Text): ...адрес больше M <- первая замапленая страница стека U <- сюда надо обратиться, для нормального разрастания стека U U U U <- сюда мы обращаемся при линейном чтении памяти процесса ...адрес меньше Возможно ничего страшного и не происходит, и стек просто мапится, но в нем анмапленая дыра: Код (Text): ...адрес больше M <- первая замапленая страница стека U U U M <- сюда мы обратились при линейном чтении памяти процесса ...адрес меньше А возможно обработчик исключения просто зафалился: Код (Text): ...адрес больше M <- первая замапленая страница стека U U U U <- сюда мы обратились, но обработчик ничего не замапил ...адрес меньше Откуда уверенность, что это .NET? По идее в прикладухах без нета тогда проявляться не должно... Хотя если ты уже все расковырял... поделись плиз.. Кстати, может .нет создает треды с большим резервным стеком?
semen То что это не стек обычно говорят три вещи - крупный под 30Мбайт размер, ужасающая медленная скорость чтения под 5мб/сек, и при том что аттрибуты региона обьявленны как RW, записывать в него ничего совершенно не получается (а стек допускает обычно запись). Уверенности большой нет, просто регион как правило находится в Visual Studio.NET (после сборки некоторого проекта). И в некоторых играх (у моего приятеля вообще было на всех, что меня до крайности смутило - может у него драйверы видеокарты Sapphire 9800Pro эту технологию юзали) только размер как правило больше - 128Мбайт. Все никак недоходят ручки собрать простейшее .NET приложение, и на нам потестить.
alpet Ну дык запусти тред с dwStackSize равным 30 метрам - что возможно вижал студия и делает =). Скорость низкая - из-за вызова исключения каждый раз. Не пишется, потому что возможно стек защищен. Чем не объяснения? Вроде все сходится, потому и написал. По край ней мере логичное предположение, а не расплывчатые догадки. Для железок вроде много памяти, кроме видяхи, а для видяхи скорость тоже мала, даже на чтение(которое в АГП медленно), да и не должна видеопамять быть замеплена в обычных прогах, да и регионов несколько. С .NET мне кажется вообще абсурд, не настока он пока вездесущь и если нет импорта mscoree.dll, то и быть его в процессе вообще не должно. Так что кроме стека ничего на ум не приходит.
semen Нет. Стеком это быть не может. На сколько я себе преставляю - регион в который писать нельзя стеком быть не может. Да и расширение стека в худших условиях происходит с скоростью выделения страниц в файле подкачки (на моем компе это порядка 30мб/сек - и в этом случае работает hdd), а тут 5мб/сек. Очень интересно, что этот регион полностью инициализирован - заполнен одно образными значениями, в основном 0x00D4D0C8 (в тексте это "ИРФ\0"). Еще один довод - стек никогда не выглядит как регион с аттрибутом MEM_MAPPED (эквивалент проекции файла), обычно он MEM_PRIVATE. Почему стал - думать на .NET - здесь где-то написано - у Visual Studio зарезервированно очень похожее количество памяти под .NET CLR Memory-># Total reserved Bytes = 33546160. Вобщем варианты остаются - это действия драйвера .NET CLR (при чтении региона проц грузится на 100%, причем из ядра) по управлению доступом к памяти (у него это дело ведь навороченное), и - это проекция файла драйвера, хотя я не думаю что такое возможно. Что еще говорит в пользу .NET - при запуске Visual Studio, CLR сразу не загружается, а только через какое то время (событие к этому приводящее, я еще не отловил). Надо ли говорить, что при этом злополучного региона в VS нет.