Это должно вести себя под управлением ОС Linux? (потому что это кажется ужасным ...)

Когда моя система Linux приближается к поисковому вызову (т. е. в моем случае 16 ГБ RAM почти заполнен, своп 16 ГБ полностью пуст), если новый процесс X пытается выделить некоторую память, система полностью блокирует. То есть до тех пор, пока непропорциональное количество страниц (по отношению к общему размеру и скорости запросов на распределение памяти X) не будет заменено. Обратите внимание, что не только gui становится полностью невосприимчивым, но даже основные сервисы, такие как sshd, полностью блокируются.

Это два фрагмента кода (по общему признанию, грубые), которые я использую, чтобы вызвать это поведение более «научным» способом. Первый получает два числа x, y из командной строки и переходит к выделять и инициализировать несколько кусков y байтов, пока не будет выделено больше, чем х байтов. А потом просто спит неопределенно. Это будет использоваться, чтобы привести систему к грани пейджинга.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv) {
   long int max = -1;
   int mb = 0;
   long int size = 0;
   long int total = 0;
   char* buffer;

   if(argc > 1)
     {
       max = atol(argv[1]);
       size = atol(argv[2]);
     }
   printf("Max: %lu bytes\n", max);
   while((buffer=malloc(size)) != NULL && total < max) {
       memset(buffer, 0, size);
       mb++;
       total=mb*size;
       printf("Allocated %lu bytes\n", total);       
   }      
   sleep(3000000);
   return 0;
}

Вторая часть кода выполняет именно то, что делает первый, за исключением того, что он имеет код sleep(1); сразу после printf (я не буду повторять весь код). Этот будет использоваться, когда система находится на грани пейджинга, чтобы заставить его обмениваться страницами «мягким» способом, т. Е. Медленно запрашивая выделение новых блоков памяти (чтобы система, безусловно, могла менять страницы и не отставать от новых запросов).

Итак, скомпилированные две части кода, давайте назовем exe fasteater и sloweater, давайте сделаем следующее:

1) запустите свой любимый gui (не обязательно обязательно)

2) запустите некоторый измеритель mem /swap (например, watch -n 1 free)

3) запустите несколько экземпляров fasteater x y, где x имеет порядок гигабайт, а y - порядка мегабайт. Сделайте это, пока вы почти не заполните баран.

4) запустите один экземпляр sloweater x y, где x имеет порядок гигабайт, а y - порядка мегабайт.

После шага 4), что должно произойти (и это всегда происходит для моей системы) - это то, что после исчерпания штока система полностью заблокируется. gui заблокирован sshd заблокирован и т. д. НО, не навсегда! После того, как sloweater завершит свои запросы на распределение, система вернется к жизни (после минут блокировки, а не секунд ...) с этой ситуацией:

a) ram имеет значение full

b) swap также полностью заполнен (помните, что он был пуст в начале)

c) нет вмешательства убийцы oom.

И обратите внимание, что раздел подкачки находится на SSD. Таким образом, система, по-видимому, не может постепенно перемещать страницы из ram в swap (предположительно из спасителей, которые только что спят), чтобы освободить место для медленных (и всего нескольких мегабайт) запросов замедлителя.

Теперь, кто-то исправит меня, если я ошибаюсь, но это не похоже на то, как современная система должна вести себя в этой ситуации. Кажется, что он ведет себя как старые системы (waaaaay back), когда не было поддержки пейджинга, и система виртуальной памяти просто поменяла место для всей памяти некоторого процесса вместо нескольких страниц.

Кто-нибудь может это проверить? И, возможно, кто-то, у которого также есть система BSD.

ОБНОВЛЕНИЕ 1 Я следил за советом Mark Plotnick ниже в комментариях, и я начал vmstat 1 >out, прежде чем продолжить тестирование пейджинга. Вы можете увидеть результат ниже (я вырезал всю начальную часть, где барабан заполнен без участия swap):

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
0  0   6144 160792      8 272868    0    0     0     0  281 1839  1  0 99  0  0
0  0   6144 177844      8 246096    0    0     0     0  425 2300  1  1 99  0  0
0  0   6144 168528      8 246112    0    0    16     0  293 1939  1  0 99  0  0
0  0   6144 158320      8 246116    0    0     0     0  261 1245  0  0 100  0  0
2  0  10752 161624      8 229024    0 4820 17148  4820  845 3656  1  2 97  0  0
2  0  10752 157300      8 228096    0    0 88348     0 2114 8902  0  5 94  1  0
0  0  10752 176108      8 200052    0    0 108312     0 2466 9772  1  5 91  3  0
0  0  10752 170040      8 196780    0    0 17380     0  507 1895  0  1 99  0  0
0 10  10752 160436      8 191244    0    0 346872    20 4184 17274  1  9 64 26  0
0 29 12033856 152888      8 116696 5992 15916880 1074132 15925816 819374 2473643  0 94  0  6  0
3 21 12031552 295644      8 136536 1188    0 11348     0 1362 3913  0  1 10 89  0
0 11 12030528 394072      8 151000 2016    0 17304     0  907 2867  0  1 13 86  0
0 11 12030016 485252      8 158528  708    0  7472     0  566 1680  0  1 23 77  0
0 11 12029248 605820      8 159608  900    0  2024     0  371 1289  0  0 31 69  0
0 11 12028992 725344      8 160472 1076    0  1204     0  387 1381  0  1 33 66  0
0 12 12028480 842276      8 162056  724    0  3112     0  357 1142  0  1 38 61  0
0 13 12027968 937828      8 162652  776    0  1312     0  363 1191  0  1 31 68  0
0  9 12027456 1085672      8 163260  656    0  1520     0  439 1497  0  0 30 69  0
0 10 12027200 1207624      8 163684  728    0   992     0  411 1268  0  0 42 58  0
0  9 12026688 1331492      8 164740  600    0  1732     0  392 1203  0  0 36 64  0
0  9 12026432 1458312      8 166020  628    0  1644     0  366 1176  0  0 33 66  0

Как вы можете видеть, как только происходит обмен, происходит всплеск 15916880 Кбайт, который, как мне кажется, длится всю продолжительность зависания системы. И все это, по-видимому, вызвано процессом (медленным), который просто запрашивает 10 МБ каждую секунду.

ОБНОВЛЕНИЕ 2: Я быстро установил freebsd и повторил ту же схему распределения, что и с linux ... и она была такой же гладкой, как и должна быть. freebsd постепенно менял страницы, в то время как sloweater выделял все свои 10 Мбайт кусков памяти. Не одна зацепка любого типа ... WTF здесь происходит ?!

ОБНОВЛЕНИЕ 3: Я отправил ошибку . с ядром bugtracker. Кажется, это привлекло некоторое внимание ... пальцы скрещены ...

13 голосов | спросил John Terragon 3 Maypm18 2018, 19:08:57

1 ответ


-2

Вы только выделяете память - вы на самом деле ничего не вкладываете в нее. «Обычная» программа выделила бы кусок и затем начала его использовать. Выделение не совпадает с использованием памяти.

ответил Jeremy Boden 23 Maypm18 2018, 16:43:37

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132