免费论文网 首页

linux内存管理

时间:2018-11-09 11:25 来源:免费论文网

篇一:LINUX系统基本的内存管理知识讲解

内存是Linux内核所管理的最重要的资源之一。内存管理系统是操作系统中最为重要的部分,因为系统的物理内存总是少于系统所需要的内存数量。虚拟内存就是为了克服这个矛盾而采用的策略。系统的虚拟内存通过在各个进程之间共享内存而使系统看起来有多于实际内存的内存容量。Linux支持虚拟内存, 就是使用磁盘作为RAM的扩展,使可用内存相应地有效扩大。核心把当前不用的内存块存到硬盘,腾出内存给其他目的。当原来的内容又要使用时,再读回内存。

一、内存使用情况监测

(1)实时监控内存使用情况

在命令行使用Free命令可以监控内存使用情况

代码如下:

#free

total used free shared buffers cached

Mem: 256024 192284 63740 0 10676 101004

-/+ buffers/cache: 80604 175420

Swap: 522072 0 522072

上面给出了一个256兆的RAM和512兆交换空间的系统情况。第三行输出(Mem:)显示物理内存。total列不显示核心使用的物理内存(通常大约1MB)。used列显示被使用的内存总额(第二行不计缓冲)。 free列显示全部没使用的内存。Shared列显示多个进程共享的内存总额。Buffers列显示磁盘缓存的当前大小。第五行(Swap:)对对换空间,显示的信息类似上面。如果这行为全0,那么没使用对换空间。在缺省的状态下,free命令以千字节(也就是1024字节为单位)来显示内存使用情况。可以使用—h参数以字节为单位显示内存使用情况,或者可以使用—m参数以兆字节为单位显示内存使用情况。还可以通过—s参数使用命令来不间断地监视内存使用情况:

#free –b –s2

这个命令将会在终端窗口中连续不断地报告内存的使用情况,每2秒钟更新一次。

(2)组合watch與 free命令用来实时监控内存使用情况:

代码如下:

#watch -n 2 -d free

Every 2.0s: free Fri Jul 6 06:06:12 2007

total used free shared buffers cached

Mem: 233356 218616 14740 0 5560 64784

-/+ buffers/cache: 148272 85084

Swap: 622584 6656 615928

watch命令会每两秒执行 free一次,执行前会清除屏幕,在同样位置显示数据。因为 watch命令不会卷动屏幕,所以适合出长时间的监测内存使用率。可以使用 -n选项,控制执行的频率;也可以利用 -d选项,让命令将每次不同的地方显示出来。Watch命令会一直执行,直到您按下 [Ctrl]-[C] 为止。

二、虚拟内存的概念

(1)Linux虚拟内存实现机制

Linux虚拟内存的实现需要六种机制的支持:地址映射机制、内存分配回收机制、缓存和刷新机制、请求页机制、交换机制、内存共享机制。

首先内存管理程序通过映射机制把用户程序的逻辑地址映射到物理地址,在用户程序运行时如果发现程序中要用的虚地址没有对应的物理内存时,就发出了请求页要求;如果有空闲的内存可供分配,就请求分配内存(于是用到了内存的分配和回收),并把正在使用的物理页记录在缓存中(使用了缓存机制)。 如果没有足够的内存可供分配,那么就调用交换机制,腾出一部分内存。另外在地址映射中要通过TLB(翻译后援存储器)来寻找物理页;交换机制中也要用到交换缓存,并且把物理页内容交换到交换文件中后也要修改页表来映射文件地址。

(2)虚拟内存容量设定

也许有人告诉你,应该分配2倍于物理内存的虚拟内存,但这是个不固定的规律。如果你的物理保存比较小,可以这样设定。如果你有1G物理内存或更多的话,可以缩小一下虚拟内存。Linux会把大量的内存用做Cache的,但在资源紧张时回收回.。你只要看到swap为0或者很小就可以放心了,因为内存放着不用才是最大的浪费。

三、使甩vmstat命令监视虚拟内存使用情况

vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监视。它是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析。通常使用vmstat 5 5(表示在5秒时间内进行5次采样)命令测试。将得到一个数据汇总它可以反映真正的系统情况。

代码如下:

#vmstat 5 5

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----

r b swpd free buff cache si so bi bo in cs us sy id wa

1 0 62792 3460 9116 88092 6 30 189 89 1061 569 17 28 54 2

0 0 62792 3400 9124 88092 0 0 0 14 884 434 4 14 81 0

0 0 62792 3400 9132 88092 0 0 0 14 877 424 4 15 81 0

1 0 62792 3400 9140 88092 0 0 0 14 868 418 6 20 74 0

1 0 62792 3400 9148 88092 0 0 0 15 847 400 9 25 67 0

vmstat命令输出分成六个部分:

(1)进程procs:

r:在运行队列中等待的进程数 。

b:在等待io的进程数 。

(2)内存memoy:

swpd:现时可用的交换内存(单位KB)。

free:空闲的内存(单位KB)。

buff: 缓冲去中的内存数(单位:KB)。

cache:被用来做为高速缓存的内存数(单位:KB)。

(3) swap交换页面

si: 从磁盘交换到内存的交换页数量,单位:KB/秒。

so: 从内存交换到磁盘的交换页数量,单位:KB/秒。

(4) io块设备:

bi: 发送到块设备的块数,单位:块/秒。

bo: 从块设备接收到的块数,单位:块/秒。

(5)system系统:

in: 每秒的中断数,包括时钟中断。

cs: 每秒的环境(上下文)切换次数。

(6)cpu中央处理器:

cs:用户进程使用的时间 。以百分比表示。

sy:系统进程使用的时间。 以百分比表示。

id:中央处理器的空闲时间 。以百分比表示。

如果 r经常大于 4 ,且id经常小于40,表示中央处理器的负荷很重。 如果bi,bo 长期不等于0,表示物理内存容量太小。

四、Linux 服务器的内存泄露和回收内存的方法

1、内存泄漏的定义:

一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显示释放的内存。应用程序一般使用malloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。

2、内存泄露的危害

从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。存在内存泄漏问题的程序除了会占用更多的内存外,还会使程序的性能急剧下降。对于服务器而言,如果出现这种情况,即使系统不崩溃,也会严重影响使用。

3、内存泄露的检测和回收

对于内存溢出之类的麻烦可能大家在编写指针比较多的复杂的程序的时候就会遇到。在

Linux 或者 unix 下,C、C++语言是最使用工具。但是我们的 C++ 程序缺乏相应的手段来检测内存信息,而只能使用 top 指令观察进程的动态内存总额。而且程序退出时,我们无法获知任何内存泄漏信息。

使用kill命令

使用Linux命令回收内存,我们可以使用Ps、Kill两个命令检测内存使用情况和进行回收。在使用超级用户权限时使用命令Ps,它会列出所有正在运行的程序名称,和对应的进程号(PID)。Kill命令的工作原理是:向Linux操作系统的内核送出一个系统操作信号和程序的进程号(PID)。

应用例子:

为了高效率回收内存可以使用命令ps 参数v:

代码如下:

[root@www ~]# ps v

PID TTY STAT TIME MAJFL TRS DRS RSS %MEM COMMAND

2542 tty1 Ss+ 0:00 0 8 1627 428 0.1 /sbin/mingetty tty1

2543 tty2 Ss+ 0:00 0 8 1631 428 0.1 /sbin/mingetty tty2

2547 tty3 Ss+ 0:00 0 8 1631 432 0.1 /sbin/mingetty tty3

2548 tty4 Ss+ 0:00 0 8 1627 428 0.1 /sbin/mingetty tty4

2574 tty5 Ss+ 0:00 0 8 1631 432 0.1 /sbin/mingetty tty5

2587 tty6 Ss+ 0:00 0 8 1627 424 0.1 /sbin/mingetty tty6

2657 tty7 Ss+ 1:18 12 1710 29981 7040 3.0 /usr/bin/Xorg :0 -br -a

2670 pts/2 Ss 0:01 2 682 6213 1496 0.6 -bash

3008 pts/4 Ss 0:00 2 682 6221 1472 0.6 /bin/bash

3029 pts/4 S+ 0:00 2 32 1783 548 0.2 ping 192.168.1.12

3030 pts/2 R+ 0:00 2 73 5134 768 0.3 ps v

然后如果想回收Ping命令的内存的话,使用命令:

篇二:Linux 内存管理

计算机操作系统课程小论文

Linux内存管理机制

姓名:汪青松

班级:10网络工程1班

学号:1004031010

Linux内存管理机制

班级:10级网络工程1班姓名:汪青松学号:1004031010

一、 概述

现代操作系统允许多个程序同时运行,因此,内存中需要同时存放这些程序,操作系统采用的存储管理方案有分区存储管理、分页式存储管理、分段式存储管理和段页式存储管理。

在Linux平台上,多任务运行是不可或缺的,在合理的进程调度算法控制下还得合理的管理内存机制,除了在物理内存的支持下,Linux还得借助虚拟内存等来容纳更多的程序运行,没有足够的内存空间来供程序运行,机器则会出现假死机、服务异常等问题,如果Linux虽然可以在一段时间内自行恢复,但是恢复后的系统已经基本不可用了。因此,合理规划和设计Linux内存的使用,是非常重要的。

二、 Linux下内存管理框架

在Linux中对于内存的管理涉及到:页面管理、连续内存区管理和非连续存储区管理,而对于内存管理的方式通常为直接使用、使用slab分配器和使用非连续的存储区。其

Linux采用页作为内存管理的基本单位,其采用的标准的页面大小为4KB,采用三次映射机制实现从线性地址到物理地址的映射。Linux内核使用页描述符来跟踪和管理物理内存,每个物理页面都用一个页描述符表示,页描述符用struct page 的结构描述,所有物理页面的描述符组织在men_map数组中,page则是对物理页面描述的一个数据结构Linux采用buddy算法来解决内存的碎片问题。

三、 Linux对虚拟内存的管理

在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然。这是Linux内存管理的一个优秀特性,在这方

面,区别于Windows的内存管理。主要特点是,无论物理内存有多大,Linux 都将其充份利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的数据访问性能。而Windows 是只在需要内存时,才为应用程序分配内存,并不能充分利用大容量的内存空间。换句话说,每增加一些物理内存,Linux 都将能充分利用起来,发挥了硬件投资带来的好处,而Windows只将其做为摆设,即使增加8GB甚至更大。Linux 的这一特性,主要是利用空闲的物理内存,划分出一部份空间,做为cache 和 buffers ,以此提高数据访问性能。从而引出物理内存的特性。

对于从物理内存中虚拟出来的内存可以解决内存容量的问题,还拥有许多的附加功能:诸如大地址空间;进程保护;内存映射;灵活分配物理内存;共享虚拟内存等。

Linux对于虚拟内存的管理以进程为基础,如32位的线性进程映射到4Gb的虚拟空间中去,从0XC0000000到0XFFFFFFFF的1Gb空间为所用进程所共享的内核空间,每个进程都有自己的3Gb用户空间。

四、 Linux对物理内存的管理

在Linux中对于物理内存的管理主要是通过页面的方式

(一)、物理内存的页面管理

在内存基本框架中已经提起,Linux对于物理内存的空间主要是通过分页的方式来进行管理的,其具体做法就是将物理内存划分成大小相同的物理页面。在X86平台下每个页面的大小为4KB,4KB是大多数磁盘块大小的倍数,传输效率高,管理方便。Linux设置了一个mem_map数组管理内存页面,它开始时由free_area_init()来初始化创建,并且放在物理内存的底部。

(图一)mem_map数组结构

(图二)Buddy算法

(二)、空闲页面的管理(Buddy算法)

Buddy的基本思想是:首先把内存中的所有页面按照2n划分其中n=0~5,对一个内存空间按1个页面、2个页面、4个页面、8 个页面、16个页面、32 个页面进行六次划分,划分后形成了大小不等的存储块称为页面块,简称页块。包含1个页面的页块称为1页块,包含2个页面的称为2页块,依此类推。Linux 把物理内存划分成了1、2、4、8、16、32六种页块。对于每种页面块按前后顺序两两结合成一对 Buddy"伙伴"按照1页面划分后,0和1页、2和3页……是1页块Buddy。按照2页面划分,0-1和2-3、4-5和6-7……是2页块。

BuddyLinux 把空闲的页面按照页块大小分组进行管理,用数组free_area[]来管理各个空闲页块组。

在linux/mm/page_alloc.c中定义如下:

#define NR_MEN_LIST 6

Static struct free_area_struct free_men[NR_MEN_LIST];

Struct free_area_struct{

Struct page *next;

Struct page *prev;

Unsigned int *map;

}

五、 内存空间的分配和释放

(一)、物理内存分配

Linux中在申请和释放较小的内存时,使用kmalloc()和kfree()在物理内存中进行分配。这些内存是实际存在的,并且是连续的,并且是根据slab块来分配。kmalloc()和kfree()分配和释放内存是以块(block)为单位进行的。可以分配的空闲块的大小记录在blocksize表中,它是一个静态数组,定义在/mm/kmalloc.c中:在使用kmalloc()分配空闲块时仍以Buddy算法为基础,

即以free_area[]管理的空闲页面块做为分配对象。重新制定了分配的单位, blocksize[]数组中的块长度。它可以分配比1个页面更小的内存空间。blocksize[]中的前7个是在1个空闲页面内进行分配,其后的6种分别对应free_area[]的1至32空闲页面块,当申请分配的空间小于或等于1个页面时,从free_area[]管理的1页面块中查找空闲页面进行分配。若申请的空间大于一个页面时,按照blocksize[]后六个块单位进行申请,从free_area[]中与该块长度对应的空闲页块组中查找空闲页面块。

Free_area数组定义如下:

Typedef struct free_area_struct{

Struct list_head free_list;

Unsigned int *map;

}free_area_t;

(二)、虚拟内存分配

在分配在物理申请较大的内存空间时,使用vmalloc()。由vmalloc()申请的内存空间在虚拟内存中是连续的,它们映射到在物理内存时,可以使用不连续的物理页面,而且仅把当前访问的部分放在物理页面中。

Vmalloc申请内存如下:

#define A_MEGABYTE 1024*1024

int main(){

char *some_memery;

int megabyte=A_MEGABYTE;

int exit_code=EXIT_FAILURE;

some_memery=(char*)valloc(megabyte); /* 申请内存 */

if(some_memery!=NULL){

sprintf(some_memery,"Hello world!\n"); /* 将字符串写入 some_memery 所 指向内存 */

printf("%s",some_memery);

篇三:linux内存管理实验报告

操作系统实验报告

院别:XXXXXX

班级:XXXXXX

学号:XXXXXX

姓名:稻草人

实验题目:内存管理实验

一、 实验目的

1、 通过本次试验体会操作系统中内存的分配模式;

2、 掌握内存分配的方法(FF,BF,WF);

3、 学会进程的建立,当一个进程被终止时内存是如何处理被

释放块,并当内存不满足进程申请时是如何使用内存紧凑;

4、 掌握内存回收过程及实现方法;

5、 学会进行内存的申请释放和管理;

二、 实验内容

附源代码:

/*宏定义*/

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#define PROCESS_NAME_LEN 32 /*进程名称的最大长度*/

#define MIN_SLICE10 /*最小碎片的大小*/

#define DEFAULT_MEM_SIZE 1024/*默认内存的大小*/

#define DEFAULT_MEM_START 0/*默认内存的起始位置*/

/* 内存分配算法 */

#define MA_FF1

#define MA_BF2

#define MA_WF3

int mem_size=DEFAULT_MEM_SIZE;/*内存大小*/

int ma_algorithm = MA_FF; /*当前分配算法*/

int flag = 0;

int algorithm; /*设置内存大小标志*/ static int pid = 0; /*初始pid*/

/*描述每一个空闲块的数据结构*/

struct free_block_type{

int size;

int start_addr;

struct free_block_type *next;

};

/*指向内存中空闲块链表的首指针*/

struct free_block_type *free_block;

/*每个进程分配到的内存块的描述*/

struct allocated_block{

int pid;

int size;

int start_addr;

char process_name[PROCESS_NAME_LEN];

struct allocated_block *next;

};

/*进程分配内存块链表的首指针*/

struct allocated_block *allocated_block_head = NULL;

struct allocated_block *find_process(int id)

{

struct allocated_block *p;

}

void swap(int *p,int *q)

{

int temp;

temp = *p;

*p = *q;

*q = temp;

return; p=allocated_block_head; while(p!=NULL) { if (p->pid==id) } return NULL; return p;

void do_exit()

{

exit(0);

}

/*初始化空闲块,默认为一块,可以指定大小及起始地址*/

struct free_block_type* init_free_block(int mem_size){

struct free_block_type *fb;

fb=(struct free_block_type *)malloc(sizeof(struct free_block_type)); if(fb==NULL){

printf("No mem\n");

return NULL;

}

fb->size = mem_size;

fb->start_addr = DEFAULT_MEM_START;

fb->next = NULL;

return fb;

}

/*显示菜单*/

display_menu(){

printf("\n");

printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE); printf("2 - Select memory allocation algorithm\n");

printf("3 - New process \n");

printf("4 - Terminate a process \n");

printf("5 - Display memory usage \n");

printf("0 - Exit\n");

}

/*设置内存的大小*/

set_mem_size(){

int size;

if(flag!=0){ //防止重复设置

printf("Cannot set memory size again\n");

return 0;

}

printf("Total memory size =");

scanf("%d", &size);

if(size>0) {

mem_size = size;

free_block->size = mem_size;

}

flag=1; return 1;

}

/*按FF算法重新整理内存空闲块链表*/

rearrange_FF(){

struct free_block_type *tmp, *work;

printf("Rearrange free blocks for FF \n"); tmp = free_block;

while(tmp!=NULL)

{ work = tmp->next;

while(work!=NULL){

if ( work->start_addr < tmp->start_addr){ /*地址递增*/

swap(&work->start_addr, &tmp->start_addr); swap(&work->size, &tmp->size);

}

work=work->next;

}

tmp = tmp -> next;

}

}

/*按BF最佳适应算法重新整理内存空闲块链表*/

rearrange_BF(){

struct free_block_type *tmp, *work;

printf("Rearrange free blocks for BF \n"); tmp = free_block;

while(tmp!=NULL)

{ work = tmp->next;

while(work!=NULL){

if ( work->size > tmp->size) { /*地址递增*/ swap(&work->start_addr, &tmp->start_addr); swap(&work->size, &tmp->size);

}

work=work->next;

}

tmp = tmp -> next;

}

}


linux内存管理
由:免费论文网互联网用户整理提供,链接地址:
http://m.csmayi.cn/meiwen/26206.html
转载请保留,谢谢!
相关阅读
最近更新
推荐专题