Linux的内存模型,一般为:

现在的每个进程使用了全部4G线性空间。在加载程序时内核把程序加载到线性地址0x08048000开始的位置。这个位置当然>128MB。2G开始是共享库,3G开始是内核。

地址------------------------作用--------------------------说明

>=0xc0000000---------内核虚拟存储器-------------用户代码不可见区域

< 0xc0000000----------Stack(用户栈)------------ESP指向栈顶,向下增长

-------------------------------------------------空闲内存

>=0x40000000---------文件映射区------------------mmap的空间

< 0x40000000-------------------------------------空闲内存

---------------------Heap(运行时堆)--------------通过brk/sbrk系统调用扩大堆,向上增长。

---------------------.data、.bss(读写段)---------从可执行文件中加载

>=0x08048000---------.init、.text、.rodata-------从可执行文件中加载

< 0x08048000---------保留区域--------------------

1.         第一点是关于运行时堆的。

为说明这个问题,我们先运行一个测试程序,并观察其结果:

#include <stdio.h>

int main(int argc, char* argv[])

{

int  first = 0;

int* p0 = malloc(1024);

int* p1 = malloc(1024 * 1024);

int* p2 = malloc(512 * 1024 * 1024 );

int* p3 = malloc(1024 * 1024 * 1024 );

printf("main=%p print=%p/n", main, printf);

printf("first=%p/n", &first);

printf("p0=%p p1=%p p2=%p p3=%p/n", p0, p1, p2, p3);

getchar();

return 0;

}

运行后,输出结果为:

main=0x8048404 print=0x8048324

first=0xbfcd1264

p0=0x9253008 p1=0xb7ec0008 p2=0x97ebf008 p3=0x57ebe008

l         main和print两个函数是代码段(.text)的,其地址符合表一的描述。

l         first是第一个临时变量,由于在first之前还有一些环境变量,它的值并非0xbfffffff,而是0xbfcd1264,这是正常的。

l         p0是在堆中分配的,其地址小于0x4000 0000,这也是正常的。

l         但p1和p2也是在堆中分配的,而其地址竟大于0x4000 0000,与表一描述不符。

原因在于:运行时堆的位置与内存管理算法相关,也就是与malloc的实现相关。关于内存管理算法的问题,我们在后继文章中有详细描述,这里只作简要说明。在glibc实现的内存管理算法中,Malloc小块内存是在小于0x4000 0000的内存中分配的,通过brk/sbrk不断向上扩展,而分配大块内存,malloc直接通过系统调用mmap实现,分配得到的地址在文件映射区,所以其地址大于0x4000 0000。

从maps文件中可以清楚的看到一点:

00514000-00515000 r-xp 00514000 00:00 0

00624000-0063e000 r-xp 00000000 03:01 718192     /lib/ld-2.3.5.so

0063e000-0063f000 r-xp 00019000 03:01 718192     /lib/ld-2.3.5.so

0063f000-00640000 rwxp 0001a000 03:01 718192     /lib/ld-2.3.5.so

00642000-00766000 r-xp 00000000 03:01 718193     /lib/libc-2.3.5.so

00766000-00768000 r-xp 00124000 03:01 718193     /lib/libc-2.3.5.so

00768000-0076a000 rwxp 00126000 03:01 718193     /lib/libc-2.3.5.so

0076a000-0076c000 rwxp 0076a000 00:00 0

08048000-08049000 r-xp 00000000 03:01 1307138    /root/test/mem/t.exe

08049000-0804a000 rw-p 00000000 03:01 1307138    /root/test/mem/t.exe

09f5d000-09f7e000 rw-p 09f5d000 00:00 0          [heap]

57e2f000-b7f35000 rw-p 57e2f000 00:00 0

b7f44000-b7f45000 rw-p b7f44000 00:00 0

bfb2f000-bfb45000 rw-p bfb2f000 00:00 0          [stack]

2.         第二是关于多线程的。

现在的应用程序,多线程的居多。表一所描述的模型无法适用于多线程环境。按表一所述,程序最多拥有上G的栈空间,事实上,在多线程情况下,能用的栈空间是非常有限的。为了说明这个问题,我们再看另外一个测试:

#include <stdio.h>

#include <pthread.h>

void* thread_proc(void* param)

{

int  first = 0;

int* p0 = malloc(1024);

int* p1 = malloc(1024 * 1024);

printf("(0x%x): first=%p/n",    pthread_self(), &first);

printf("(0x%x): p0=%p p1=%p /n", pthread_self(), p0, p1);

return 0;

}

#define N 5

int main(int argc, char* argv[])

{

int first = 0;

int i= 0;

void* ret = NULL;

pthread_t tid[N] = {0};

printf("first=%p/n", &first);

for(i = 0; i < N; i++)

{

pthread_create(tid+i, NULL, thread_proc, NULL);

}

for(i = 0; i < N; i++)

{

pthread_join(tid[i], &ret);

}

return 0;

}

运行后,输出结果为:

first=0xbfd3d35c

(0xb7f2cbb0): first=0xb7f2c454

(0xb7f2cbb0): p0=0x84d52d8 p1=0xb4c27008

(0xb752bbb0): first=0xb752b454

(0xb752bbb0): p0=0x84d56e0 p1=0xb4b26008

(0xb6b2abb0): first=0xb6b2a454

(0xb6b2abb0): p0=0x84d5ae8 p1=0xb4a25008

(0xb6129bb0): first=0xb6129454

(0xb6129bb0): p0=0x84d5ef0 p1=0xb4924008

(0xb5728bb0): first=0xb5728454

(0xb5728bb0): p0=0x84d62f8 p1=0xb7e2c008

我们看一下:

主线程与第一个线程的栈之间的距离:0xbfd3d35c - 0xb7f2c454=0x7e10f08=126M

第一个线程与第二个线程的栈之间的距离:0xb7f2c454 - 0xb752b454=0xa01000=10M

其它几个线程的栈之间距离均为10M。

也就是说,主线程的栈空间最大为126M,而普通线程的栈空间仅为10M,超这个范围就会造成栈溢出。

栈溢出的后果是比较严重的,或者出现Segmentation fault错误,或者出现莫名其妙的错误。

转载于:https://www.cnblogs.com/SZLLQ2000/p/5108833.html

Linux的Application 内存模型---相关推荐

  1. 简单说一linux内核的内存模型(平坦,不连续,稀疏等三种内存模型)

    目录 Linux内核支持的三种内存模型 CONFIG_FLATMEM(平坦内存模型) 基本概念(以第一个为例,不在复述) 所以说什么是平坦模型 所以说什么是不连续模型 所以说什么是稀疏模型 总结 鸣谢 ...

  2. 探索 Linux 内存模型--转

    引用:http://www.ibm.com/developerworks/cn/linux/l-memmod/index.html 理解 Linux 使用的内存模型是从更大程度上掌握 Linux 设计 ...

  3. Linux与jvm内存关系分析

    原文出处: 美团技术团队 引言 在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约600m,Linux自身使用大约8 ...

  4. linux查看java虚拟机内存_深入理解java虚拟机(linux与jvm内存关系)

    本文转载自美团技术团队发表的同名文章 https://tech.meituan.com/linux-jvm-memory.html 一, linux与进程内存模型 要理解jvm最重要的一点是要知道jv ...

  5. java虚拟机和内存的关系_深入理解java虚拟机(linux与jvm内存关系)

    本文转载自美团技术团队发表的同名文章 https://tech.meituan.com/linux-jvm-memory.html 一, linux与进程内存模型 要理解jvm最重要的一点是要知道jv ...

  6. Linux下C语言程序的内存布局(内存模型)

    在<虚拟地址空间以及编译模式>一节中讲到,虚拟地址空间在32位环境下的大小为 4GB,在64位环境下的大小为 256TB,那么,一个C语言程序的内存在整个地址空间中是如何分布的呢?数据在哪 ...

  7. linux 读取内存颗粒,Linux中的内存管理模型浅析

    实际上这是一个内存方面的问题.要想研究这个问题,首先我们要将题目本身搞明白.由于我对Linux内核比较熟而对Windows的内存模型几乎毫不了解,因此在这篇文章中针对Linux环境对这个问题进行探讨. ...

  8. linux内核那些事之Sparse内存模型初始化

    由于现在运行的设备中大都采用sparse内存模型,而<understanding the linux virtual memory manager>书中主要以2.4和2.6内核源码基础上进 ...

  9. 郭健: Linux内存模型——平坦、非连续与稀疏

    一.前言 在linux内核中支持3中内存模型,分别是flat memory model,Discontiguous memory model和sparse memory model.所谓memory ...

最新文章

  1. 【原创】 PostgreSQL 实现MySQL 的auto_increment 字段
  2. oracle 并行提交,如何配置Oracle并行处理(上)
  3. shell中正则表达式详解_【转】【shell】正则表达式使用详解(一)
  4. LiveVideoStackCon 2019上海 优秀出品人与讲师
  5. [Unity3D]Unity3D游戏开发Lua随着游戏的债券(于)
  6. 代码重构技巧宝典,学透本篇就足够了!
  7. 如何在面试时保持冷静_如何保持冷静并成为安全工程师
  8. 解读 SSDB、LevelDB 和 RocksDB 到 GaussDB(for Redis) 的迁移
  9. 使用EXCEL连接PGSQL
  10. Embedded Linux学习笔记—TQE9_i.MX6Q LTIB环境配置
  11. malloc函数的用法
  12. 以太网口差分电平_以太网差分信号线在两层PCB板上的布线方法
  13. 用html制作四行四列的表格,HTML表格
  14. epub电子书格式转换(E-book Conversion翻译) -- calibre
  15. 天狮集团云函数实践:自定义业务逻辑实现跨境电商全球直播
  16. 【深度学习计算机视觉实战】给深度学习计算机视觉初学者的学习和求职建议,这个行业还缺人
  17. 计算机 蚂蚁搬家 教案,大班科学活动教案:小蚂蚁搬家教案(附教学反思)
  18. Stronger Data Poisoning Attacks Break Data Sanitization Defenses
  19. 多人赛跑用多线程实现
  20. 最新版的快递单号生成查询工具 测试版

热门文章

  1. 10倍加速!爱奇艺超分辨模型加速实践
  2. CV方向介绍 | 基于自然语言的跨模态行人ReID的SOTA方法简述(下)
  3. html5网页制作图文混排,03第3章制作图文混排网页.docx
  4. mycat两个mysql实例的搭建_Mycat-多实例的搭建
  5. 【TensorFlow】TensorFlow从浅入深系列之十三 -- 教你深入理解模型持久化(模型保存、模型加载)
  6. 综述 | 知识图谱(Knowledge graph)链路预测(Link Prediction)
  7. 公开课精华 | 移动机器人视觉三维感知的现在与将来
  8. Python数据分析模块 | pandas做数据分析(一):基本数据对象
  9. 计算机视觉 | Python OpenCV 3 使用背景减除进行目标检测
  10. 无人车制胜关键:Apollo决策系统全面剖析