Обнаружение записи страницы памяти в Windows и Linux

В настоящее время я работаю над сборщиком мусора поколений. Это означает, что просматриваются только самые последние объекты, а уцелевшие объекты (= доступные из известных корней) продвигаются к более старому поколению. Это работает нормально, когда объекты указывают на другие объекты того же или более старого поколения. Однако, когда старые объекты указывают на более новые, и поскольку обходятся только более новые объекты, указанные объекты будут собираться неправильно. Чтобы избежать этого, такие объекты помечаются и просматриваются явно во время каждой фазы GC.

Очевидно, что такие «родительские» объекты изменяемы, поскольку неизменяемые по своей конструкции всегда указывают на существующие объекты. Таким образом, чтобы стать «родителем», объект должен быть изменен после повышения, чтобы он указывал на более новый объект.

Чтобы узнать, какие объекты старшего поколения указывают на младшие поколения, я ищу способ прозрачно отслеживать изменения памяти. Для этого я использую защиту памяти и обработку сигналов/исключений. Страницы памяти устанавливаются только для чтения, что вызывает возбуждение сигнала/исключения всякий раз, когда они записываются, и в этом случае я снова устанавливаю защиту памяти на чтение-запись и регистрирую адрес где-то для дальнейшей обработки, а по возвращении ответственный код для исключения возобновляется нормально. Таким образом, когда срабатывает GC, я знаю, где искать потенциальных родителей для обхода.

В Linux я использую комбинацию обработки сигналов mprotect/SIGSEGV. В Windows я намереваюсь использовать VirtualProtect, но не нашел эквивалента обработки SIGSEGV. Итак, мои вопросы:

  1. Как бы вы сделали это в Windows? API обработки исключений кажется довольно запутанным.

  2. Есть ли лучший способ узнать, какие области памяти изменяются, чтобы мне не приходилось вести всю эту бухгалтерию?

Мой код написан на простом C. В настоящее время мне нужно, чтобы вызывающий код явно помечал измененные объекты, но это утомительно и подвержено ошибкам, поэтому я ищу прозрачный способ сделать это.

Заранее спасибо, Фред


person fbonnet    schedule 11.10.2011    source источник
comment
Структурированная обработка исключений.   -  person bmargulies    schedule 11.10.2011
comment
Я не настолько эксперт, чтобы сказать, действительно ли это актуально, но вы можете посмотреть этот пост в блоге относительно подводные камни одного из видов пробного зондирования памяти.   -  person    schedule 11.10.2011
comment
SEH, к сожалению, требует 1. поддержки компилятора и 2. обертывания блоков try вокруг клиентского кода, поэтому он не подходит для моей цели. Однако VEH может работать.   -  person fbonnet    schedule 12.10.2011
comment
FWIW, высокопроизводительные виртуальные машины обычно записывают указатель на ловушку при создании машинного кода (например, в JIT) и выдают код, который также записывает подсказку о грязной странице в специальный массив, потому что использование виртуальной машины для выполнения работы очень медленное.   -  person Logan Bowers    schedule 05.02.2012


Ответы (1)


GetWriteWatch идеально подходит для этого. Документация здесь

person Max DeLiso    schedule 11.10.2011
comment
Спасибо, это именно та функция, которую я ищу. Я знал об этой функции, но сначала быстро отклонил ее, потому что она требует XP и не работает с 32-разрядными приложениями на 64-разрядном Itanium. Но так как альтернативы также требуют XP, я думаю, мне придется отказаться от поддержки Win2000. - person fbonnet; 12.10.2011