`
csd_ali
  • 浏览: 133982 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

linux内存模型

阅读更多

0. 内存基本知识

        我们通常称 linux的内存子系统为:虚拟内存子系统(virtual memory system),为何这样称谓呢?

        其实这个是个很牛的设计。linux充分利用了程序的局部性原理,结合线性地址的概念(虚拟地址)使得运行于操作系统上的每个进程都可以使用所有用户空间主存。而且虚拟内存还解决了内存不连续和碎片的问题(因为在程序来说线性地址都是连续的);每个进程都有各自的页表,虚拟地址空间都各自独立,互补干扰;

        那么我们的程序里申请的内存的时候,linux内核其实只分配一个虚拟内存( 线性地址),并没有分配实际的物理内存。只有当程序真正使用这块内存时,才会分配物理内存。这就叫做延迟分配和请页机制。释放内存时,先释放线性区对应的物理内存,然后释放线性区;

        什么时候内核为进程划分物理内存的呢? 当进程执行时,申请的内存只是一块虚拟内存区域,而不是实际的物理内存,只是获得了一块虚拟内存区域上线性地址区间的使用权。实际的物理内存只有当进程真的去访问新获得的虚拟地址时,才会由"请页机制"产生"缺页"异常,从而进入分配实际页框的例程。此异常会告诉内核去真正为进程分配物理页,并建立对应的页表。这之后虚拟地址才实实在在的映射到了物理内存上了。"请页机制"将物理内存的分配延后了,这样是充分利用了程序的局部性原来,节约内存空间,提高系统吞吐;

        那么cpu执行指令访存,使用的都是物理内存地址,而我们的编译器生成的二进制码实际上分配的都是逻辑内存(逻辑地址);那么线性地址是如何转换为物理内存地址的呢?我们知道内存模型里有,段,页机制来寻址内存的;(物理内存也是划分为页为单位划分的) ;我们的程序主要分为数据段,代码段;数据段存放代码里已初始化数据,代码段存放可执行代码指令;linux通过段机制将我们程序的逻辑地址转换为线性地址,又通过页机制将线性地址转换为物理地址。

 

1. 内存布局

     我们编写的程序是如何在内存中布局的呢?

     我们知道Linux内核启动起来时,如果是4G内存,那么会有大约1G被内核占用。其他3G会被用户进行使用。我们稍后会讲解内核内存如何和用户内存通信。

     一个进程对应的内存空间包含一下5个区:

     代码段:存放可执行文件的操作指令;

     数据段:存放可执行文件申请已经初始化的全局变量;

     BSS段:  存放未初始化的全局变量;

     堆:      存放用户程序运行中,动态申请的内存空间;

     栈:      存放用户程序运行中,临时创建的局部变量;我们知道CPU有寄存器是直接可以访问栈的,所以栈比堆快多了。

 

    那么既然每个进程都有各自的虚拟内存空间,各自互不相干,那么进程间如何共享内存,内核又是如何向进程空间传递数据?  都是通过映射实现的,通过将内核的虚拟内存映射到当前进程用户空间的虚拟内存,当然映射时,要新建一个页表;  

2. 虚拟内存管理

    简单的说linux的虚拟内存管理技术:让每个进程看上去可以使用整个用户空间主存。通过 线性地址加上swap机制; swap机制:如果一个正在被cpu执行的进程恰巧和另外一个进程的线性地址指向了同一块物理内存。那么Linux通过swap机制,将这块内存写到磁盘上,叫做唤出。被唤出的数据,在使用时,又被换入;

    linux还通过cache+buffer机制: 将最近使用过的数据尽量cache,buffer起来,以便稍后会使用到;这就是说我们的可用内存=free + buffer + cache;

 

 

  • 大小: 948 Bytes
  • 大小: 969 Bytes
分享到:
评论
2 楼 ljl_ss 2011-09-21  
gogole_09 写道
实际的物理内存只有当进程真的去访问新获得的虚拟地址时,才会由"请页机制"产生"缺页"异常,从而进入分配实际页框的例程。此异常会告诉内核去真正为进程分配物理页,并建立对应的页表。这之后虚拟地址才实实在在的映射到了物理内存上了。"请页机制"将物理内存的分配延后了,这样是充分利用了程序的局部性原来,节约内存空间,提高系统吞吐
对这里有点疑惑?
   如果进程真正去访问虚拟地址的时候,有没有可能虚拟地址实际对应的物理内存空间被其他进程优先占用掉呢?
  

这个时调用swap机制
1 楼 gogole_09 2011-05-25  
实际的物理内存只有当进程真的去访问新获得的虚拟地址时,才会由"请页机制"产生"缺页"异常,从而进入分配实际页框的例程。此异常会告诉内核去真正为进程分配物理页,并建立对应的页表。这之后虚拟地址才实实在在的映射到了物理内存上了。"请页机制"将物理内存的分配延后了,这样是充分利用了程序的局部性原来,节约内存空间,提高系统吞吐
对这里有点疑惑?
   如果进程真正去访问虚拟地址的时候,有没有可能虚拟地址实际对应的物理内存空间被其他进程优先占用掉呢?
  

相关推荐

    大内高手(基于linux的内存模型)

    关于内存.大内高手(基于linux的内存模型)

    一种新的适用于Nandflash的Linux内存交换模型.pdf

    一种新的适用于Nandflash的Linux内存交换模型.pdf

    浅析Linux内存架构模型.pdf

    浅析Linux内存架构模型.pdf

    论文研究-一种新的适用于Nandflash的Linux内存交换模型.pdf

    在Linux上,内存交换有着特殊的作用,块设备在当前的Linux内核上充当交换区时,工作得很好;Nandflash在写入数据之前需要先擦除,因此当Nandflash充当交换区时,当前的内存交换模型就需要改进,否则内存交换就不能...

    Linux内存管理教学文档

    关于Linux内存管理的经典文档,嵌入式linux驱动基础,linux字符设备驱动,linux设备驱动模型

    C语言内存精讲,让你彻底明白C语言的运行机制!

    8. Linux下C语言程序的内存布局(内存模型) 9. Windows下C语言程序的内存布局(内存模型) 10. 用户模式和内核模式 11. 栈(Stack)是什么?栈溢出又是怎么回事? 12. 一个函数在栈上到底是怎样的? 13. 函数调用...

    JVM入门实战/arthas实战/垃圾回收算法/垃圾回收器/jvm内存模型分析

    第二节:JVM内存模型 1.1 概念 1.2 JVM内存模型 1.3 Heap堆内存模型 第三节:定位垃圾对象的依据 1.1 引用计数法 1.2 可达性算法 第四节:垃圾回收算法 1.1标记清除算法 1.2复制算法 1.3 标记整理(标记压缩)...

    LinuxC语言实现生产者和消费者模型

    LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC语言实现生产者和消费者模型LinuxC...

    linux epoll模型

    所以,剩下的select模型基本上就成为我们在linux上面的唯一选择,其实,如果加上no-block socket的配置,可以完成一个"伪"AIO的实现,只不过推动力在于你而不是os而已。不过传统的select/poll函数有着一些无法忍受...

    Linux内核地址映射模型与Linux内核高端内存详解

    Linux内核地址映射模型x86 CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存。段页式机制如下图。linux内核地址空间划分通常32位Linux内核地址空间划分0~3G为...

    头哥实践平台操作系统实训四 Linux 共享内存2

    头哥实践平台操作系统实训四 Linux 共享内存2

    Linux设备驱动程序学习

    ·Linux设备驱动程序学习(8)-分配内存 ·Linux设备驱动程序学习(10)-时间、延迟及延缓操作 ·Linux设备驱动程序学习(11)-中断处理 ·Linux设备驱动程序学习(3-补)-Linux中的循环缓冲区 ·Linux设备驱动程序...

    Linux进程间通信之共享内存

    Linux进程间通信之共享内存.适用于任意两个进程间,本程序为基本模型,实现了共享内存.

    Linux 驱动学习笔记pdf文档

    ·Linux设备驱动程序学习(8)-分配内存 ·Linux设备驱动程序学习(10)-时间、延迟及延缓操作 ·Linux设备驱动程序学习(11)-中断处理 ·Linux设备驱动程序学习(3-补)-Linux中的循环缓冲区 ·Linux设备驱动程序...

    Linux常见驱动源码分析(kernel hacker修炼之道全集)--李万鹏

    Linux驱动修炼之道-内存映射.pdf Linux驱动修炼之道-看门狗框架源码分析.pdf Linux驱动修炼之道-触摸屏驱动之s3c2410_ts源码分析.pdf Linux驱动修炼之道-SPI驱动框架源码分析(中).pdf Linux驱动修炼之道-...

    互斥锁+共享内存封装库,实现进程间通讯(Linux)

    Linux下提供了多种共享内存的通讯机制,常用的就是socket,但是socket通讯使用简单,但性能不佳,最优的方式还是共享内存方式。本章分享封装库,的就是基于共享内存实现的。 本分享库是基于Ubuntu16.04编译的,如需...

    linux系统进程间通信——共享内存(System V版本)

    之前用过Prosix版本的共享内存和信号量,一直没有实践System V版本的,主要是因为其信号量集的概念操作有些复杂,今天试着写一个SV版本的共享内存进程间通信,使用信号量同步。程序提供了几个简单的用于操作SV版本...

    Linux-Kernel Memory Model.pdf

    描述linux系统的内存一致性模型,介绍了硬件一致性模型以及linux提供了哪些方法可以用于保证顺序一致性,其中讲述了内存屏障的使用方式和原理。

    Linux编程--Linux内核

    2.1 虚拟内存抽象模型 15 2.1.1 请求调页 17 2.1.2 交换 17 2.1.3 共享虚拟内存 18 2.1.4 物理寻址模式和虚拟寻址模式 18 2.1.5 访问控制 18 2.2 高速缓存 19 2.3 Linux页表 20 2.4 页分配和回收 21 2.4.1 页分配 22...

    Linux网络编程 视频 教程

    Linux网络编程(总共41集) 讲解Linux网络编程知识,分以下四个篇章。 Linux网络编程之TCP/IP基础篇 Linux网络编程之socket编程篇 Linux网络编程之进程间通信篇 Linux网络编程之线程篇 Linux网络编程之TCP/IP...

Global site tag (gtag.js) - Google Analytics