Home > Linux, Tutorial > Program Stress Test untuk Beban Memori

Program Stress Test untuk Beban Memori

Penasaran dengan apa yang dilakukan oleh setelan swappiness yang mengatur kecenderungan kernel untuk memindahkan proses dari memori ke disk swap, membawa saya untuk mencari program stress test yang dapat mengkonsumsi memori dengan besar yang dapat diatur. Dengan menjalankan program stress test tersebut, perilaku kernel dalam menempatkan proses (program yang dijalankan) ke memori (RAM) dan disk swap bisa diamati.

Kata kunci yang saya gunakan adalah “stress test memory linux”. Muncullah beberapa tautan halaman, di antaranya Linux: How to put a load on system memory? dan How to fill 90% of the free memory?. Dari kedua halaman tersebut, terdapat beberapa solusi di antaranya menggunakan skrip bash, python dan program.

Salah satu program yang bisa digunakan adalah stress. Program stress ini dapat memberikan beban CPU, memori dan disk ke sistem dengan tingkat yang diinginkan.Di Linux Ubuntu, program stress ini telah tersedia dapat dapat diinstall dengan apt.

$sudo apt-get install stress

Contoh perintah untuk mengisi 90% memori yang kosong dengan stress adalah

$ stress --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1

Stress test saya lakukan ke server Linux 14.03 dengan memori dan swap masing-masing 1 GB. Parameter swappiness diset 0 (versi kernel 3.5 keatas, harusnya ini akan menonaktifkan swap, tapi kita lihat nanti). Program stress dijalankan dengan menggunakan 2 thread (worker) yang menggunakan 95% memori yang bebas (free), yaitu 894060k dari 941240k, sehingga total 2 thread akan memakan sekitar 1788120k dan kernel mulai menggunakan disk swap untuk menyimpan proses.

$ uname -a
Linux base-ubuntu-server 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ free
             total       used       free     shared    buffers     cached
Mem:       1016864      75624     941240        424       4064      11848
-/+ buffers/cache:      59712     957152
Swap:      1044476          0    1044476
$ awk '/MemFree/{printf "%d\n", $2 * 0.95;}' < /proc/meminfo
894060
$ sysctl vm.swappiness
vm.swappiness = 0
$ stress --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.95;}' < /proc/meminfo)k --vm-keep -m 2
$ watch -n 1 free
             total       used       free     shared    buffers     cached
Mem:       1016864     924428      92436          4        196       2908
-/+ buffers/cache:     921324      95540
Swap:      1044476    1014288      30188

Disk swap akan tetap aktif walaupun swappiness = 0. Kernel akan mulai memindahkan proses ke swap saat memori bebasnya sekitar 80-90M (atau sekitar 8%).

Cek kembali dengan memberikan beban agar penggunaan memori 99% RAM yang tersedia. Hanya 1 worker yang dijalankan.

$ free
             total       used       free     shared    buffers     cached
Mem:       1016860     109068     907792        404      10656      47272
-/+ buffers/cache:      51140     965720
Swap:      1044476          0    1044476
$ awk '/MemFree/{printf "%d\n", $2 * 0.99;}' < /proc/meminfo
898714
$ stress --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.99;}' < /proc/meminfo)k --vm-keep -m 1
$ watch -n 1 free
           total       used       free     shared    buffers     cached
Mem:       1016860     942900      73960         32       1412       4620
-/+ buffers/cache:     936868      79992
Swap:      1044476      12940    1031536

Hasilnya masih konsisten. Setelan vm.swappiness = 0 masih membuat kernel menggunakan swap saat sistem kehabisan memori.

Catatan tambahan

  • Halaman bantuan program stress:
$ stress --help
`stress' imposes certain types of compute stress on your system
Usage: stress [OPTION [ARG]] ...
 -?, --help         show this help statement
     --version      show version statement
 -v, --verbose      be verbose
 -q, --quiet        be quiet
 -n, --dry-run      show what would have been done
 -t, --timeout N    timeout after N seconds
     --backoff N    wait factor of N microseconds before work starts
 -c, --cpu N        spawn N workers spinning on sqrt()
 -i, --io N         spawn N workers spinning on sync()
 -m, --vm N         spawn N workers spinning on malloc()/free()
     --vm-bytes B   malloc B bytes per vm worker (default is 256MB)
     --vm-stride B  touch a byte every B bytes (default is 4096)
     --vm-hang N    sleep N secs before free (default is none, 0 is inf)
     --vm-keep      redirty memory instead of freeing and reallocating
 -d, --hdd N        spawn N workers spinning on write()/unlink()
     --hdd-bytes B  write B bytes per hdd worker (default is 1GB)
     --hdd-noclean  do not unlink files created by hdd workers
Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s
Note: Numbers may be suffixed with s,m,h,d,y (time) or B,K,M,G (size).
  • Kode program C untuk beban memori:
#include 
#include 
#define UNIX 1
//remove the above line if running under Windows
#ifdef UNIX
    #include 
#else
    #include 
#endif
int main(int argc, char** argv)
{
    unsigned long mem;
    if(argc==1)
        mem = 1024*1024*512; //512 mb
    else if(argc==2)
        mem = (unsigned) atol(argv[1]);
    else
    {
        printf("Usage: loadmem ");
        exit(1);
    }
    char* ptr = malloc(mem);
    while(1)
    {
        memset(ptr, 0, mem);
        #ifdef UNIX
            sleep(120);
        #else
            Sleep(120*1000);
        #endif
    }
}
  • Kode program C untuk beban CPU
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define CPUUSAGE 0.3      /* set it to a 0 < float < 1 */
#define PROCESSES 1       /* number of child worker processes */
#define CYCLETIME 50000   /* total cycle interval in microseconds */
#define WORKTIME (CYCLETIME * CPUUSAGE)
#define SLEEPTIME (CYCLETIME - WORKTIME)
/* returns t1-t2 in microseconds */
static inline long timediff(const struct timeval *t1, const struct timeval *t2)
{
  return (t1->tv_sec - t2->tv_sec) * 1000000 + (t1->tv_usec - t2->tv_usec);
}
static inline void gettime (struct timeval *t)
{
  if (gettimeofday(t, NULL) < 0)
  {
    err(1, "failed to acquire time");
  }
}
int hogcpu (void)
{
  struct timeval tWorkStart, tWorkCur, tSleepStart, tSleepStop;
  long usSleep, usWork, usWorkDelay = 0, usSleepDelay = 0;
  do
  {
    usWork = WORKTIME - usWorkDelay;
    gettime (&tWorkStart);
    do
    {
      sqrt (rand ());
      gettime (&tWorkCur);
    }
    while ((usWorkDelay = (timediff (&tWorkCur, &tWorkStart) - usWork)) < 0);
    if (usSleepDelay <= SLEEPTIME)
      usSleep = SLEEPTIME - usSleepDelay;
    else
      usSleep = SLEEPTIME;
    gettime (&tSleepStart);
    usleep (usSleep);
    gettime (&tSleepStop);
    usSleepDelay = timediff (&tSleepStop, &tSleepStart) - usSleep;
  }
  while (1);
  return 0;
}
int main (int argc, char const *argv[])
{
  pid_t pid;
  int i;
  for (i = 0; i < PROCESSES; i++)
  {
    switch (pid = fork ())
    {
    case 0:
      _exit (hogcpu ());
    case -1:
      err (1, "fork failed");
      break;
    default:
      warnx ("worker [%d] forked", pid);
    }
  }
  wait(NULL);
  return 0;
}
  • Skrip python:
    #!/usr/bin/env python
    import sys
    import time
    if len(sys.argv) != 2:
        print "usage: fillmem "
        sys.exit()
    count = int(sys.argv[1])
    megabyte = (0,) * (1024 * 1024 / 8 )
    data = megabyte * count
    while True:
        time.sleep(1)
    
  • Skrip bash (dalam bentuk function):
    function malloc() {
      if [[ $# -eq 0 || $1 -eq '-h' || $1 -lt 0 ]] ; then
        echo -e "usage: malloc N\n\nAllocate N mb, wait, then release it."
      else
        N=$(free -m | grep Mem: | awk '{print int($2/10)}')
        if [[ $N -gt $1 ]] ;then
          N=$1
        fi
        sh -c "MEMBLOB=\$(dd if=/dev/urandom bs=1MB count=$N) ; sleep 1"
      fi
    }
    

 

 

 

Categories: Linux, Tutorial
  1. No comments yet.
*

This blog is kept spam free by WP-SpamFree.

Skip to toolbar