Нежелательные контекстные переключатели: как я могу их предотвратить?


У меня есть небольшое приложение, которое я запускал прямо сейчас, и я хотел проверить, есть ли у меня какие-либо утечки памяти, поэтому я ввел этот фрагмент кода:

for (unsigned int i = 0; i<10000; i++) {
    for (unsigned int j = 0; j<10000; j++) {
        std::ifstream &a = s->fhandle->open("test");
        char temp[30];
        a.getline(temp, 30);
        s->fhandle->close("test");
    }
}

Когда я запустил приложение я cat'ed/proc//, чтобы узнать, увеличивается ли память. Вывод следующий после примерно 2 минут времени выполнения:

Name:   origin-test
State:  R (running)
Tgid:   7267
Pid:    7267
PPid:   6619
TracerPid:  0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 256
Groups: 4 20 24 46 110 111 119 122 1000 
VmPeak:   183848 kB
VmSize:   118308 kB
VmLck:         0 kB
VmHWM:      5116 kB
VmRSS:      5116 kB
VmData:     9560 kB
VmStk:       136 kB
VmExe:        28 kB
VmLib:     11496 kB
VmPTE:       240 kB
VmSwap:        0 kB
Threads:    2
SigQ:   0/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000002004
SigCgt: 00000001800044c2
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed:   3f
Cpus_allowed_list:  0-5
Mems_allowed:   00000000,00000001
Mems_allowed_list:  0
voluntary_ctxt_switches:    120
nonvoluntary_ctxt_switches: 26475

Ни одно из значений не изменилось, кроме последнего, так же как и в среднем нет утечек памяти?

Но что более важно и что я хотел бы знать, если это плохо, последнее значение быстро растет (около 26475 переключателей примерно за 2 минуты!).

Я посмотрел на некоторые другие приложения, чтобы сравнить, сколько у них многополюсных переключателей:

  • Firefox: около 200
  • Gdm: 2
  • Netbeans: 19

Затем я погуглил и узнал кое-что, но это технически для меня, чтобы понять. Что я получил от этого, так это, когда приложение переключает процессор или что-то еще? (У меня есть 6-ядерный процессор Amd btw).

Как я могу предотвратить выполнение моим приложением и насколько это может быть проблемой при запуске приложения?

Спасибо заранее, Робин.

Ответ 1

Переключатель добровольного контекста возникает, когда ваше приложение заблокировано в системном вызове, и ядро ​​решает дать ему временный фрагмент другому процессу.

Нежелательный контекстный переключатель возникает, когда ваше приложение использует все временные листы, которые планировщик приписал ему (ядро пытается притвориться, что каждое приложение имеет весь компьютер для себя и может использовать столько CPU, которое они хотят, но должно переключаться между собой, чтобы пользователь имел иллюзию, что все они работают параллельно).

В вашем случае, поскольку вы открываете, закрываете и читаете из того же файла, он, вероятно, остается в кеше виртуальной файловой системы во время всего выполнения процесса, а программа youre выгружается ядром, поскольку это не блокируя (из-за системных или библиотечных кэшей). С другой стороны, Firefox, Gdm и Netbeans в основном ждут ввода от пользователя или из сети и не должны быть выгружены ядром.

Эти переключатели контекста не являются вредными. Напротив, это позволяет вашему процессору использоваться справедливо всем приложением, даже если один из них ждет какой-то ресурс. ≈

И BTW, чтобы обнаружить утечки памяти, лучшим решением было бы использовать инструмент, предназначенный для этого, например valgrind.

Ответ 3

Чтобы искать утечку памяти, гораздо лучше установить и использовать valgrind, http://www.valgrind.org/. Он будет идентифицировать утечки памяти в условиях ошибки кучи и памяти (используя неинициализированную память, массу других проблем). Я использую его почти каждый день.