Linux 使用者進程記憶體空間詳解

來源:互聯網
上載者:User

常使用top命令瞭解進程資訊,其中包括記憶體方面的資訊。命令top協助文檔是這麼解釋各個欄位的。

VIRT, Virtual Image (kb)

RES, Resident size (kb)

SHR, Shared Mem size (kb)

%MEM, Memory usage(kb)

SWAP, Swapped size (kb)

CODE, Code size (kb)

DATA, Data+Stack size (kb)

nFLT, Page Fault count

nDRT, Dirty Pages count

儘管有注釋,但依然感覺有些晦澀,不知所指何意?

進程記憶體空間

正在啟動並執行程式,叫進程。每個進程都有完全屬於自己的,獨立的,不被幹擾的記憶體空間。此空間,被分成幾個段(Segment),分別是Text, Data, BSS, Heap, Stack。使用者進程記憶體空間,也是系統核心分配給該進程的VM(虛擬記憶體),但並不表示這個進程佔用了這麼多的RAM(實體記憶體)。這個空間有多大?命令top輸出的VIRT值告訴了我們各個進程記憶體空間的大小(進程記憶體空間隨著程式的執行會增大或者縮小)。你還可以通過/proc//maps,或者pmap –d 瞭解某個進程記憶體空間都分布,比如:

#cat /proc/1449/maps  …  0012e000-002a4000 r-xp 00000000 08:07 3539877    /lib/i386-linux-gnu/libc-2.13.so  002a4000-002a6000 r--p 00176000 08:07 3539877    /lib/i386-linux-gnu/libc-2.13.so  002a6000-002a7000 rw-p 00178000 08:07 3539877   /lib/i386-linux-gnu/libc-2.13.so  002a7000-002aa000 rw-p 00000000 00:00 0  …  08048000-0875b000 r-xp 00000000 08:07 4072287    /usr/local/mysql/libexec/mysqld  0875b000-0875d000 r--p 00712000 08:07 4072287    /usr/local/mysql/libexec/mysqld  0875d000-087aa000 rw-p 00714000 08:07 4072287   /usr/local/mysql/libexec/mysqld  …  PS:線性地址,存取權限, offset, 裝置號,inode,對應檔

VM分配與釋放

“記憶體總是被進程佔用”,這句話換過來可以這麼理解:進程總是需要記憶體。當fork()或者exec()一個進程的時候,系統核心就會分配一定量的VM給進程,作為進程的記憶體空間,大小由BSS段,Data段的已定義的全域變數、靜態變數、Text段中的字元直接量、程式本身的記憶體映像等,還有Stack段的局部變數決定。當然,還可以通過malloc()等函數動態分配記憶體,向上擴大heap。

動態分配與靜態分配,二者最大的區別在於:1. 直到Run-Time的時候,執行動態分配,而在compile-time的時候,就已經決定好了分配多少Text+Data+BSS+Stack。2.通過malloc()動態分配的記憶體,需要程式員手工調用free()釋放記憶體,否則容易導致記憶體泄露,而靜態分配的記憶體則在進程執行結束後系統釋放(Text, Data), 但Stack段中的資料很短暫,函數退出立即被銷毀。

我們使用幾個樣本小程式,加深理解

/* @filename: example-2.c */#include <stdio.h>         int main(int argc, char *argv[])  {      char arr[] = "hello world"; /* Stack段,rw--- */    char *p = "hello world";        /* Text段,字串直接量, r-x--  */    arr[1] = 'l';      *(++p) = 'l';   /* 出錯了,Text段不能write */    return 0;  }

PS:變數p,它在Stack段,但它所指的”hello world”是一個字串直接量,放在Text段。

/* @filename:example_2_2.c */#include <stdio.h>  #include <stdlib.h>  #include <string.h>         char *get_str_1()  {      char str[] = "hello world";      return str;  }         char *get_str_2()  {      char *str = "hello world";      return str;  }         char *get_str_3()  {      char tmp[] = "hello world";      char *str;      str = (char *)malloc(12 * sizeof(char));      memcpy(str, tmp, 12);      return str;  }         int main(int argc, char *argv[])  {      char *str_1 = get_str_1();  //出錯了,Stack段中的資料在函數退出時就銷毀了      char *str_2 = get_str_2();  //正確,指向Text段中的字元直接量,退出程式後才會回收      char *str_3 = get_str_3();  //正確,指向Heap段中的資料,還沒free()      printf("%s\n", str_1);      printf("%s\n", str_2);      printf("%s\n", str_3);      if (str_3 != NULL)      {          free(str_3);          str_3 = NULL;      }      return 0;  }

本文URL地址:http://www.bianceng.cn/OS/Linux/201410/45418.htm

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.