Unix/Linux的内存分配

原创 2013年12月04日 23:10:12
程序员所接触的都是虚拟内存地址。每个进程都有0-4G的虚拟内存地址,本质上就是一个整数。这个整数

先天是不能够存储数据的,否则会引发段错误。虚拟内存地址,只有映射零物理内存/硬盘文件后,才能存

储数据,才占据内存。

虚拟内存地址分为用户空间和内核空间。0-3G为用户空间,3-4G是内核空间。用户空间不能直接访问内核空间,但可以通过系统提供的函数进入内核空间。内存地址的基本单位是字节,内存映射的基本单位是内存页,一个内存页是4k(或者4k的倍数)。

内存分配和回收的函数(运算符)
STL          -》 自动分配,自动回收
|
C++          -》new ,delete
|
c语言        -》malloc() free()
|
Unix系统函数 -》brk() sbrk()
|
Unix系统函数 -》mmap(),munmap()           用户层
————————————————————————————
     |
Unix系统函数 -》kmalloc()                 内核层

1)malloc 和 free

malloc只有在第一次时映射内存,一次映射33个内存页。如果用完, 才再次映射。
如果系统映射超过33页,系统就会映射稍多一点内存。

需要注意的是:

malloc分配内存时,系统会额外占用一些空间,用于存储下一个空间的 附加信息。

	int *p1 = malloc(4); //内存映射,映射33个内存页
	int *p2 = malloc(4);//只分配,不再映射内存
	int *p3 = malloc(4);
	int *p4 = malloc(12);
	printf("%p %p %p %p \n",p1,p2,p3,p4);//堆之间的地址并没有连续
//p1地址前面存放着附加信息,将附加信息清零  ==》错误:已放弃,核心已转移	
	*(p1 -1) = 0; 。
        free(p1);
free()一定释放虚拟内存,但是不保证解除物理内存的映射,而且最后的33个内存页是无法free的,进程
结束才能解除最后的33个内存页。为了提高效率,用空间换时间。

例如,我首先分配内存

void *p = malloc(1);//此时系统一次性映射了33个内存页
free(p);  //此时并没有解除物理内存的映射.

2) sbrk 和 brk

sbrk()和brk()底层维系了一个位置。通过位置的移动来分配和回收内存。
void sbrk(intptr_T increment)

increment 移动增量负数逆向移动(释放内存),正数向前移动(分配内存),

为0返回当前位置。成功返回移动之前的位置,失败返回零。
sbrk实打实的每次一次分配一页空间,如果超出一页就再分配一页。

        char *p_num = sbrk(4);//分配了四个字节的内存,返回首地址
	*p_num = 100;
	printf("%d\n",*p_num);  //打印出100
	sbrk(-4);//释放3个字节内存,返回值没有意义
brk 函数决定了所分配空间的结尾地址.如下:

	void *p = sbrk(0);//返回当前地址,并不映射内存。
	brk(p+4); //分配了四个字节,映射了一页地址。
	brk(p+8); //重新分配四个字节
	brk(p+4);//回收四个字节 
sbrk用来分配内存方便,而brk用来释放内存更方便.(两个函数都可以用来分配和释放内存)
//分配空间存放int
	int *pi = (int*)sbrk(4);
	*pi = 100;
//分配空间存放double
	double *pd = (double*)sbrk(8);
	*pd = 1.0;
//分配空间存放string
 	char *p_str = (char*)sbrk(6);
	strcpy(p_str,"abcde");
//释放所有空间
	brk(pi);
3)mmap,munmap

用来映射或者取消映射.代码如下:

#include<sys/mman.h>
#include<unistd.h>
#include<string.h>
int main()
{
	void *p_map = mmap(0,  //内核选择虚拟首地址
	1,  //映射的字节数,不足内存页补足
	PROT_READ | PROT_WRITE,//读写权限
	MAP_SHARED | MAP_ANONYMOUS,//共享,匿名
	-1,0);  //映射一页内存
	if( p_map == MAP_FAILED)
	{
		perror("mmap");
		return -1;
	}
	int *pi = p_map;
	*pi = 100;

	strcpy(pi + 4,"kongdeju"); //证明映射了一页。
	printf("%d,%s\n",*pi,(char*)(pi + 4));
	munmap(p_map,1);//取消映射
	return 0;
}




浅谈Unix/linux下的内存管理

程序和内存的概念   程序是指在硬盘上的可执行文件。当程序被运行时,需要将可执行文件加载到内存,在内存中的可执行文件形成进程,一个进程(文件)可以同时存在多个进程(内存)。   内存区域的划分...
  • qq_26369213
  • qq_26369213
  • 2015年06月04日 22:51
  • 1002

windows和linux下Tomcat内存的分配与溢出的配置详解

windows和linux下Tomcat内存的分配与溢出的配置详解 源代码下载地址:http://www.zuidaima.com/share/1795452574026752.htm...
  • yaerfeng
  • yaerfeng
  • 2016年05月28日 10:19
  • 889

unix下使用共享内存实现进程间通信

一、什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存...
  • crazy_programmer_p
  • crazy_programmer_p
  • 2014年07月12日 12:01
  • 743

linux 内存分配机制

这几天在观察apache使用内存情况,所以特意了解了下linux的内存机制,发现一篇写得还不错。转来看看。 一般来说在ps aux中看到的rss就是进程所占用的物理内存。但是如果将所有程序的rss加...
  • koozxcv
  • koozxcv
  • 2015年10月28日 17:02
  • 1724

linux内核内存的详细分配

我们知道CPU所访问的都是虚拟内存地址。那么平时我们自己在编写的内核模块时,linux到底分配的是什么样的 内存空间呢?要解答这个问题,首先就要看看内核非连续内存。 在linux的内存管理中,用户使用...
  • YuZhiHui_No1
  • YuZhiHui_No1
  • 2015年08月04日 22:23
  • 4076

Linux系统如何为进程分配内存

可执行程序的内存分布 GNU编译器生成的目标文件默认格式为elf(executive linked file)格式,这是Linux系统所采用的可执行链接文件的通用文件格式。elf格式由若干个...
  • qq_32744005
  • qq_32744005
  • 2016年07月05日 13:20
  • 1703

linux内核内存分配

内核中的内存分配通常通过kmalloc/kfree来进行,但是也有其它的方式来获取内存,所有这些方式共同提供了内核中分配、释放内存的接口。 一、kmalloc/kfree 类似于标准C中的malloc...
  • goodluckwhh
  • goodluckwhh
  • 2013年11月18日 20:56
  • 4906

linux内存分配方法总结--总结的不错

转自:http://blog.chinaunix.net/uid-22028680-id-3968085.html 转自:http://www.cnblogs.com/wenhuisun/arc...
  • JK198310
  • JK198310
  • 2013年11月21日 13:27
  • 839

Linux内存布局、内存分配原理

Linux的虚拟内存管理有几个关键概念 1.每个进程有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址 2.虚拟地址可通过每个进程的页表与物理地址进行映射,获得真正物理地址 3....
  • b2222505
  • b2222505
  • 2017年05月21日 22:09
  • 2151

Linux内存空间的分配

1、Linux内存空间 a. Linux的内存空间有4G的进程地址空间,包括用户空间与内核空间。用户空间分配了3G,而内核空间分配了1G。用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间...
  • zhengqijun_
  • zhengqijun_
  • 2016年07月11日 11:00
  • 1405
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unix/Linux的内存分配
举报原因:
原因补充:

(最多只允许输入30个字)