Linux虚拟内存映射之brk/sbrk,map/munmap
来源:互联网 发布:淘宝联盟是返利吗 编辑:程序博客网 时间:2024/06/05 23:46
一.关于虚拟内存
问题:
一个程序不能访问另外一个程序的地址指向的空间.
理解:
1.每个程序的开始地址ox8048000(?可由objdump 反汇编得到)
2.程序中使用的地址不是物理地址,而是逻辑地址(虚拟内存).
逻辑地址仅仅是编号.编号使用int 4字节整数表示.
4294967296=4G
每个程序提供了4G的访问能力(32位机,下同)
问题:
逻辑地址与物理地址关联才有意义:过程称为内存映射.
背景:
虚拟内存的提出:禁止用户直接访问物理存储设备.
有助于系统的稳定.
结论:
虚拟地址与物理地址映射的时候有一个基本单位:至少会映射4K
4k 1000 内存页.
段错误:无效访问. 那段内存没有映射
合法访问:比如malloc分配的空间之外的空间可以访问,但访问非法.因是越界访问
内存访问分两种:一个是可以访问,但不一定是合法的,比如malloc几个字节,
内存会给你映射4K空间,int*p=malloc(0); *(p+1000)=9999;理论说这是可以访问,但是非法的,它可能破坏维护malloc分配的数据结构,就跟虚表指针一样。
二.虚拟内存的分配
栈:编译器自动生成代码维护
堆:地址是否映射?映射的空间是否被管理?
1.brk/sbrk内存映射函数
分配释放内存:
int brk(void *end);//分配空间,释放空间
void *sbrk(int size);//返回空间地址
应用:
1.使用sbrk分配空间
2.使用sbrk得到没有映射的虚拟地址.
第一次调用sbrk,sbrk(0)得到的是没有映射的虚拟首地址。
3.使用brk分配空间
4.使用brk释放空间
理解:
sbrk(int size)
如果是第一次运行,则返回没有映射的空闲空间首地址,同时产生一个数据:指向地址
sbrk与brk后台系统维护一个指针.
指针默认是null.
调用sbrk,判定指针是否是0,
是:得到大块空闲空间的首地址初始化指针.同时把指针+size
否:返回指针,并且把指针位置+size
demo:
#include <stdio.h>#include <unistd.h>main(){int *p=sbrk(0); //返回的是空闲空间的首地址,然后系统给映射一个页//*p=800; //段错误int *p1=sbrk(4);//返回空闲地址,然后系统给映射4K 并修改指针为+size//先看一下指针是否为空,如果是空,就返回空闲空间的首地址,//然后再看里面的参数是几个字节,再看一下这几个字节是否有空间,//没空间的话就映射空间,然后把指针+4*(p1+10)=4000; //可以访问,反正系统给映射了4K空间大小,但是是非法的int *p2=sbrk(0); //返回的是首地址+4 p2=sbrk(200);int *p3=sbrk(0); //得到的地址是首地址+204int *p4=sbrk(-4);//释放4个字节的空间int *p5=sbrk(-4);printf("%p\n",p);printf("%p\n",p1);printf("%p\n",p2);printf("%p\n",p3);printf("%p\n",p4);printf("%p\n",p5);printf("%d\n",getpid());/*int *p=sbrk(0);brk(p+1);//brk改变的是绝对位置*p=800;*/brk(p);//*p=99;//段错误//while(1);}/*输出:0x89090000x89090000x89090040x89090cc0x89090cc0x89090c815945*/
应用案例:
写一个程序查找1-10000之间所有的素数.
并且存放到缓冲,然后打印.
缓冲的实现使用sbrk/brk
流程:
循环
判定是否素数(isPrimer)
是,分配空间存放
不是,继续下步.
#include <stdio.h>#include <unistd.h>int isPrimer(int a){int i;for(i=2;i<a;i++){if(a%i==0) return 1;}return 0;}main(){int i=2;int b;int *r;int *p;p=sbrk(0);r=p;for(;i<100;i++){b=isPrimer(i);if(b==0){brk(r+1);*r=i;r=sbrk(0);}}i=0;r=p;while(r!=sbrk(0)){printf("%d\n",*r);r++;}brk(p);//free}
2.mmap/munmap内存映射函数
没有任何额外维护数据的内存分配。
mmap(分配)/unmap(释放)
1.函数说明
void *mmap(
void *start,//指定映射的虚拟地址 0由系统指定开始位置)
size_t length,//映射空间大小pagesize倍数
int prot,//映射权限 PROT_NONE | PROT_READ PROT_WRITE PROT_EXEC
intflags,//映射方式
int fd,//文件描述符号
offset_t off);//文件中的映射开始位置(必须是pagesize的倍数)
映射方式:
内存映射:匿名映射。
文件映射:映射到某个文件
只有文件映射最后两个参数有效。
MAP_ANONYMOUS
MAP_SHARED MAP_PRIVATE(二选一)
2.demo
#include <unistd.h>#include <sys/mman.h>#include <stdlib.h>#include <stdio.h>main(){int *p=mmap(NULL,getpagesize(),PROT_READ,MAP_ANONYMOUS|MAP_SHARED,0,0);*p=20;*(p+1)=30;*(p+2)=40;printf("%d\n",p[2]);munmap(p,4096);}
三.总结:
智能指针(指针池)
STL
new
malloc (小而多数据)
brk/sbrk (同类型的大块数据,动态移动指针)
mmap/munmap(控制内存访问/使用文件映射/控制内存共享)异常处理
int brk(void*)
void *sbrk(int);
如果成功.brk返回0 sbrk返回指针
失败 brk返回-1 sbrk返回(void*)-1- Linux虚拟内存映射之brk/sbrk,map/munmap
- Linux虚拟内存-brk/sbrk
- linux brk、sbrk、mmap和munmap系统调用
- linux编程学习笔记(三) 虚拟内存映射 brk sbrk mmap umap
- 内存管理-sbrk()/brk()、mmap()/munmap()
- UC编程03-内存分配与内存映射函数sbrk/brk/mmap/munmap
- linux 环境编程之 map,munmap 内存映射文件
- brk和sbrk的虚拟内存的管理
- 系统调用与内存管理(sbrk、brk、mmap、munmap)
- linux学习---brk(), sbrk() 用法
- linux之文件映射mmap/munmap
- brk/sbrk
- brk sbrk
- linux sbrk/brk函数使用整理
- Linux sbrk/brk函数使用整理
- Linux sbrk/brk函数使用整理
- linux内存映射 mmap munmap
- Linux虚拟内存管理(glibc) mmap sbrk
- Core Data could not fulfill a fault
- IOS中十七个常用代码整理
- Hadoop Fair Scheduler
- C++中的运算符重载(一)
- 不同皮肤洗脸的方法-----先收藏这
- Linux虚拟内存映射之brk/sbrk,map/munmap
- Real-Rime Rendering (10) - 图形硬件及学习小结(Graphics Hardware)
- JPEG讲解
- 异步调用和回调函数
- 黎活明给程序员的忠告
- uva 1533 - Moving Pegs(BFS)
- 嵌入式Linux交叉编译工具链安装方法
- 黑马程序员---JAVA基础---IO(十三)
- 自我检查,看清自己 看清自己什么皮肤。