Эффекты диского кеша во время выделения памяти в приложениях
Дисковый кеш не мешает приложениям в получении памяти, которой им необходимы. Вот небольшая программа на языке С (munch.c) которая выделяет столько памяти, сколько сможет или до определенного лимита:
$ cat munch.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
int max = -1;
int mb = 0;
char* buffer;
if(argc > 1)
max = atoi(argv[1]);
while((buffer=malloc(1024*1024)) != NULL && mb != max) {
memset(buffer, 0, 1024*1024);
mb++;
printf("Allocated %d MB\n", mb);
}
return 0;
}
Когда память заканчивается - это не круто, но OOM-killer должен убить только этот процесс и надеюсь остальные процессы он не затронет.
Отключим для начала swap, что бы приложение не начало съедать его.
Отключим для начала swap, что бы приложение не начало съедать его.
$ sudo swapoff -a
Проверим состояние памяти:
$ free -m
total used free shared buffers cached
Память: 7866 7720 146 0 619 2443
-/+ буферы/кэш: 4657 3209
Swap: 0 0 0
Скомпилируем нашу программу:
$ gcc munch.c -o munch
И запустим:
$ ./munch
Allocated 1 MB
...
Allocated 3139 MB
Убито
$ free -m
total used free shared buffers cached
Память: 7866 4980 2886 0 14 965
-/+ буферы/кэш: 4000 3866
Swap: 0 0 0
Не смотря на то, что было свободно свободно 146 Мб памяти - это не помешало приложению съесть 3139 Мб. После чего ООМ-killer убил процесс и освободил память.
В логе видим такое:
Jun 13 16:02:40 wimbo-hp kernel: [185540.658308] munch invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
Включим swap:
$ swapon -a
$ swapon -a
Проверим состояние памяти:
$ free -m
$ free -m
total used free shared buffers cached
Память: 7866 4793 3073 0 3 812
-/+ буферы/кэш: 3977 3889
Swap: 7627 251 7376
Запустим программу, что бы она выделила себе 3300 Мб:
$ ./munch 3300
Allocated 1 MB
...
Allocated 3300 MB
И снова проверим состояние памяти:
$ free -m
total used free shared buffers cached
Память: 7866 4499 3367 0 0 536
-/+ буферы/кэш: 3962 3904
Swap: 7627 263 7364
munch съел 3300 Мб памяти, которая была взята из свободной и кешированной не используя swap. Кроме того, мы можем забить дисковый кеш снова и это не заставит ОС использовать swap (верно при /proc/sys/vm/swappiness = 0). Если мы в одном терминале запустим команду find . -type f -exec cat {} + > /dev/null, а в другом будем смотреть вывод free -m, то мы заметим, как растет показатель cached и снижается показатель free.
Чистка дискового кеша
Для эксперемента очень удобно, что мы можем сбросить дисковый кеш. Для этого необходимо в файл /proc/sys/vm/drop_caches записать значение 3:
# free -m
total used free shared buffers cached
Память: 7866 4726 3139 0 9 767
-/+ буферы/кэш: 3949 3917
Swap: 7627 263 7364
Сбросим дисковый кеш:
Сбросим дисковый кеш:
# echo 3 > /proc/sys/vm/drop_caches
И снова проверим состояние памяти:
И снова проверим состояние памяти:
# free -m
total used free shared buffers cached
Память: 7866 4469 3397 0 0 523
-/+ буферы/кэш: 3945 3921
Swap: 7627 263 7364
Эффективность кеша диска во время работы приложений
Давайте напишем две программы на Python и на Java. У обоих этих языков довольно большой рантайм за счет того, что они подгружают все библиотеки и енвайрамент (ВМ). Это отличный вариант, что бы продемонстрировать магию дискового кеша.
# cat hello.py
print "Hello World! Love, Python"
# cat hello.java
class Hello {
public static void main(String[] args) throws Exception {
System.out.println("Hello World! Regards, Java");
}
}
Скомпилируем программу на Java:
print "Hello World! Love, Python"
# cat hello.java
class Hello {
public static void main(String[] args) throws Exception {
System.out.println("Hello World! Regards, Java");
}
}
Скомпилируем программу на Java:
$ javac hello.java
Вот такие простые программы:
$ python hello.py
Hello World! Love, Python
$ java Hello
Hello World! Regards, Java
Сбросим дисковый кеш:
# echo 3 > /proc/sys/vm/drop_caches
И посмотрим время выполнения данных программ без кеша:
# time python hello.py
Hello World! Love, Python
real 0m1.343s
user 0m0.008s
sys 0m0.024s
# time java Hello
Hello World! Regards, Java
real 0m0.660s
user 0m0.068s
sys 0m0.028s
Довольно долго не находите для таких простых программ?
Запустим повторно:
# time python hello.py
Hello World! Love, Python
real 0m0.021s
user 0m0.016s
sys 0m0.004s
# time java Hello
Hello World! Regards, Java
real 0m0.077s
user 0m0.056s
sys 0m0.016s
Ух ты! Python выполнился в 64 раза быстрее, а Java в 8.5 раз быстрее.
Сбросим дисковый кеш:
Эффект дискового кеша на чтение файла
Давайте создадим небольшой файл и посмотрим, как дисковый кеш влияет на его скорость чтения. Я создал файл размером 500 Мб.Сбросим дисковый кеш:
# echo 3 > /proc/sys/vm/drop_caches
И посмотрим состояние памяти:
# free -m
total used free shared buffers cached
Память: 7866 4448 3418 0 1 638
-/+ буферы/кэш: 3808 4057
Swap: 7627 183 7444
Создадим файл с нулями размером 500 Мб:
# dd if=/dev/zero of=bigfile bs=1M count=500
500+0 записей получено
500+0 записей отправлено
скопировано 524288000 байт (524 MB), 1,35606 c, 387 MB/c
# ls -lh bigfile
-rw-r--r-- 1 root root 500M Июн 13 18:22 bigfile
Теперь проверим еще раз состояние памяти:
# free -m
total used free shared buffers cached
Память: 7866 5229 2637 0 7 1415
-/+ буферы/кэш: 3806 4060
Swap: 7627 183 7444
При создании файла, его содержимое пишется в дисковый кеш (кеш память увеличилась больше, чем на 500 Мб за счет того, что я выполняю все действия на ноутбуке, где запущено еще куча другого софта).
Давайте прочитаем его и посмотрим за сколько мы это сделаем:
И посмотрим состояние памяти:
# free -m
total used free shared buffers cached
Память: 7866 4448 3418 0 1 638
-/+ буферы/кэш: 3808 4057
Swap: 7627 183 7444
Создадим файл с нулями размером 500 Мб:
# dd if=/dev/zero of=bigfile bs=1M count=500
500+0 записей получено
500+0 записей отправлено
скопировано 524288000 байт (524 MB), 1,35606 c, 387 MB/c
# ls -lh bigfile
-rw-r--r-- 1 root root 500M Июн 13 18:22 bigfile
Теперь проверим еще раз состояние памяти:
# free -m
total used free shared buffers cached
Память: 7866 5229 2637 0 7 1415
-/+ буферы/кэш: 3806 4060
Swap: 7627 183 7444
При создании файла, его содержимое пишется в дисковый кеш (кеш память увеличилась больше, чем на 500 Мб за счет того, что я выполняю все действия на ноутбуке, где запущено еще куча другого софта).
Давайте прочитаем его и посмотрим за сколько мы это сделаем:
# time cat bigfile > /dev/null
real 0m0.119s
user 0m0.004s
sys 0m0.096s
Не плохо, 500 Мб за 0,11 секунды. Давайте очистим кеш:
# echo 3 > /proc/sys/vm/drop_caches
И повторим чтение:
# time cat bigfile > /dev/null
real 0m6.008s
user 0m0.004s
sys 0m0.324s
Ух ты, видим, что при чтении файла, который не находится время, потратилось в 50 раз больше времени.
Это вольный перевод статьи: http://www.linuxatemyram.com/play.html
Комментариев нет:
Отправить комментарий