Wednesday, February 17, 2016

Memahami Stack Size Limit di Linux

Saya menulis artikel ini karna kebeneran saya sempet menghandel aplikasi yang memaksa saya menggunakan teknik ini agar salah satu aplikasi modul yang digunakan tsb tidak over limit ketika menggunakan resource dari server yang tersedia.

Sebenernya kalo dibahas lebih detail akan ada banyak case yang bisa diselesaikan dengan teknik ini sebab ini merupakan salah satu teknik tuning di level OS, tapi saya akan mempersempit penulisan dan sample casenya agar tidak melebar. Saya tulis hal ini disini sebagai catatan biar gak lupa aja.

Apabila ada temen-temen yang lebih memahami teknik ini dan apa yang saya tulis disini mungkin bisa dikoreksi catatan saya ini. 

Apa Itu Stack Size? 
Mari kita bahas apa itu stack size dalam sebuah program. Pada OS linux terdapat command ulimit yang berfungsi untuk melakukan limit resource yang dapat digunakan oleh program di OS linux.

Dibawah ini merupakan berbagai options yang dapat dibatasi oleh ulimit, yaitu :

-a     All current limits are reported
-c     The maximum size of core files created
-d     The maximum size of a process's data segment
-e     The maximum scheduling priority ("nice")
-f     The  maximum  size  of files written by the shell and its children
-i     The maximum number of pending signals
-l     The maximum size that may be locked into memory
-m     The maximum resident set size (has no effect on Linux)
-n     The maximum number of open file descriptors (most systems do not allow this value to be set)
-p     The pipe size in 512-byte blocks (this may not be set)
-q     The maximum number of bytes in POSIX message queues
-r     The maximum real-time scheduling priority
-s     The maximum stack size
-t     The maximum amount of cpu time in seconds
-u     The  maximum  number  of  processes available to a single user
-v     The maximum amount of virtual  memory available to the shell

Untuk melakukan listing ulimit yang saat ini digunakan gunakan command # ulimit -a.

[root@localhost ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7746
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7746
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Dari hasil output diatas, default stack size di OS linux saya yaitu 10240 kbytes, atau sekitar 10MB.


Lalu Bagaimana Stack Size Dapat Berdampak Pada Program yang Kita Jalankan?
Sepanjang pengalaman saya dengan kondisi default diatas yaitu stack size 10240KB atau 10MB, maka apabila ada sebuah program yang local variable size-nya lebih dari 10MB hampir dipastikan program tersebut tidak akan dapat berjalan di OS tsb.

Sebagai contoh dibawah ini ada sebuah program sederhana menggunakan bahasa C yang mereserved resource sekitar 32MB (8000000 * 4 bytes = 32000000).

[root@localhost ~]# vi test_stacksize.c
### Lalu taruh code ini di file tersebut  ###

#include <stdio.h>

int testingstack()
{
  int arifzp[8000000];

  printf("Hello Arif Zulfikar");
}

int main()
{
  testingstack();
  return 0;
}

### Apabila sudah selesai quit dan save ###


Lalu build & compile code diatas menggunakan command dibawah ini.

[root@localhost ~]# cc -o test_stacksize test_stacksize.c
[root@localhost ~]# chmod 750 test_stacksize

Lalu execute file tersebut maka outputnya adalah segmentation fault (core dumped), seperti dibawah ini.

[root@localhost ~]# ./test_stacksize 
Segmentation fault (core dumped)

Mengapa hal tersebut bisa terjadi? Hal ini disebabkan kapasitas stack size yang dialokasikan oleh OS Linux yang digunakan saat ini adalah 10240KB atau sekitar 10MB sedangkan di dalam code tersebut local variable size yang digunakan adalah 32MB (8000000 * 4 bytes = 32000000).


Lalu Bagaimana Cara Mengatasinya?
Dalam beberapa kondisi memang sebagai system engineer kita harus mampu melakukan konfigurasi yang menyesuaikan dengan kebutuhan customer dan developer kita.

Dalam kasus ini linux dapat mengubah kapasitas limit stack size yang dapat digunakan oleh OS.

Untuk mengecek stack size yang digunakan saat ini gunakan command ulimit -s. Kapasitas saat ini adalah 10MB.
[root@localhost ~]# ulimit -s
10240 

Sedangkan yang dibutuhkan adalah 32MB, untuk mengubah kapasitasnya gunakan command ulimit -s 'size'. Contoh kita akan mengubah kapasitasnya menjadi 33MB sehingga program yang tadi dibuat dapat dijalankan

[root@localhost ~]# ulimit -s 33792
[root@localhost ~]# ulimit -s
33792

Lalu jalankan lagi program tadi, dengan kondisi saat ini seharusnya program tersebut dapat berjalan.
[root@localhost ~]# ./test_stacksize 
Hello Arif Zulfikar

Dengan teknik seperti ini maka ada berbagai macam keuntungan salah satunya tidak harus mengubah source code dan mengcompile ulang sehingga mengganggu jalannya aplikasi yang sedang digunakan.

Semoga bermanfaat.

No comments:

Post a Comment