Почему мой Linux НЕ использовал ленивое выделение памяти?
Я практикуюсь в использовании политик Lazy Allocation и Demand Paging в Linux.
Мне нужен буфер, который я выделил
mmap()
не занимать физическую память, пока я действительно что-то не напишу на нее. Кроме того, я хочу, чтобы он постепенно увеличивался (использовал больше физической памяти) с размером шага размера страницы подкачки (например, 4 КБ) Linux, и я постоянно пишу от его головы к хвосту.
Согласно некоторым документам и поискам , он НЕ должен увеличиваться, если на нем есть доступ только для чтения , но реальность, которую я наблюдал в эксперименте, этого НЕ любит.
Чтобы проверить это, я закодировал программу следующим образом и наблюдал за состоянием памяти с помощью
top
команда оболочки, когда она запущена.
constexpr size_t BUF_SIZE = 1024 * 1024 * 1024;
int main( int argc, char** argv ) {
auto shm_pt = mmap( NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0 );
if( shm_pt == MAP_FAILED ) {
std::cerr << "mmap error:" << shm_pt;
exit( EXIT_FAILURE );
};
bool full_zero = true;
uint8_t* pc = reinterpret_cast<uint8_t*>( shm_pt );
constexpr size_t STEP_SIZE = 1024 * 1024;
for( size_t j = 0; j < BUF_SIZE / STEP_SIZE; ++j ) {
this_thread::sleep_for( 100ms );
size_t base = j * STEP_SIZE;
std::cerr << "Reading from " << base / 1024 / 1024 << "M..." << endl;
for( size_t i = 0; i < STEP_SIZE; ++i )
full_zero = full_zero && pc[ base + i ] == 0;
}
if( !full_zero )
std::cerr << "The buffer has not been initialized with full zeros!";
for( size_t j = 0; j < BUF_SIZE / STEP_SIZE; ++j ) {
this_thread::sleep_for( 100ms );
size_t base = j * STEP_SIZE;
std::cerr << "Writing to " << base / 1024 / 1024 << "M..." << endl;
for( size_t i = 0; i < STEP_SIZE; ++i )
pc[ base + i ] = 'c';
}
munmap( shm_pt, BUF_SIZE );
return EXIT_SUCCESS;
};
Я заметил, что физическая память, используемая моим приложением, постепенно увеличивается вместе с операцией чтения , а не с операцией записи!
Может быть, мое понимание неверно?
1 ответ
Я понял!
В поисковом содержании , которое я вставил, этот человек использовал
MAP_PRIVATE
пометить
mmap()
в качестве аргумента, в то время как я использовал
MAP_SHARED
.
Похоже, что если буфер используется совместно процессами, операция ЧТЕНИЕ также приводит к реальному выделению памяти!