Linux程序存储结构与进程结构 堆和栈的差别

摘要:本文主要讲述了Linux系统中。程序存储结构(代码区、数据段和BBS区)与进程的基本结构(代码区、数据段、BBS区、堆和栈)。以及堆和栈的差别.

Linux程序存储结构与进程结构

1.Linux程序存储结构

在Linux系统下,程序是一个普通的可运行文件,图1是一个Linux下ELF格式可运行文件的基本情况.

图1 ELF格式可运行文件的基本信息

能够看出,此ELF格式可运行文件在存储时,没有调入到内存,分为代码区(text),数据区(data)和为初始化区(bss)3个部分.各段基本说明例如以下:

(1)代码区(text segment).也称正文段.存放CPU可运行的机器指令。通常代码区是可共享的(即另外的运行代码能够訪问调用它)代码区一般是仅仅读的。使其仅仅读的原因是防止程序意外地改动了它的指令.因此,常量数据在编译时在代码段中分配空间.样例1会说明这点.

代码区的指令包括操作码和操作对象(或对象的地址引用)。假设是详细数值。将直接包括在代码中.假设是局部数据,将在执行时在栈区分配空间。然后再引用数据的地址。假设是BBS区和数据区,在代码中相同将引用该数据的地址.

(2)全局初始化数据区/静态数据区。或简称数据段.该区包括了在程序中明白被初始化的全局变量、已经初始化的静态变量(包括全局静态变量和局部静态变量).但被const声明的变量以及字符串常量在代码段中申请空间.

(3)未初始化数据区,也称BBS区.存入的是未初始化全局变量和未初始化静态变量.BBS区的数据在程序開始运行之前被内核初始化为0或者空指针(NULL).

样例1。说明常量数据在编译时在代码段中分配空间.

#include <stdio.h>
int main()
{
        char *buf =NULL;
        printf("%s\n",buf);
        return 0;
}

编译后检測各段的大小:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAwNjEwMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" height="88" width="592">

在代码中加入一个字符常量和const数据常量:

#include <stdio.h>
const int i=10;
int main()
{
        char *buf = NULL;
        printf("%s\n",buf);
        return 0;
}

又一次编译后查看:代码段的数据添加了4字节的const i.

2.Linux进程结构

在Linux系统下,假设将一个ELF格式可执行文件载入到内存中执行。则将演变成一个或多个进程.进程是Linux事务的基本管理单元,全部的进程均拥有自己的独立的环境和资源.进程的环境由当前系统状态及其父进程信息决定和组成.

一个正在执行的进程在内存空间中申请的代码区、初始化数据区、未初始化数据区、上下文信息以及挂载的信号等等.

(1)代码区.载入的是可运行文件的代码段。其载入到内存中的位置由载入器完毕.

(2)全局初始化数据区/静态数据区.载入的是可执行文件数据段。位置可位于代码段后也能够分开.程序在执行之初就为该数据段申请了空间,在程序退出时才释放,因此。存储于数据段的数据的生存周期为整个程序执行过程.

(3)未初始化数据区.载入的是可执行文件BBS段,位置能够分开也能够紧靠数据段.程序在执行之初为该部分申请了空间。在程序退出时才释放,存储于该部分的数据的生存周期为整个程序执行过程.

(4)栈.由编译器自己主动分配释放.自己主动变量以及每次函数调用所须要保存的信息都存放在此段中.每次调用函数时,其返回地址以及调用者的环境信息都存放在栈中.然后,近期被调用的函数在栈上为其自己主动和暂时变量分配存储空间.通过这样的方式使用栈。能够递归的调用C函数.递归函数每次调用自身时,就使用一个新的栈帧,因此一个函数调用实例中的变量集不会影响还有一个函数调用实例中的变量.

(5)堆,通常在堆中进行动态存储分配.一般由程序猿分配和释放,若程序猿不释放,程序结束是由系统收回.堆位于非初始化数据段和栈之间.

图2 所看到的为ELF格式可运行文件存储结构和Linux进程基本结构的对比图.

图2 可运行文件与进程存储布局

3.为什么分这么多个区?

(1)代码段和数据段分开。执行时便于分开载入,在哈佛体系结构的处理器将取得更好的流水线处理效率.

(2)代码是依次执行,由处理器的PC指针依次读入,并且代码能够被多个程序共享,数据在整个执行过程中有可能多次被使用。假设将代码和数据混合在一起将造成空间的浪费.

(3)暂时数据及须要再次使用的代码在执行时放入栈中,生命周期短,便于提高资源利用率.

(4)堆区能够由程序猿分配和释放,以便用户自由分配。提高程序的灵活性.

4.堆和栈的差别

栈是由编译器在程序执行时分配的空间。由操作系统维护.堆是由malloc()函数分配的内存块,内存的管理由程序猿手动控制,在C语言使用free()函数完毕.主要差别有一下几点:

(1)管理方式不同

程序在执行时栈由操作系统自己主动管理,无须程序猿手工控制。而堆空间的申请、释放工作由程序猿控制,easy产生内存泄露.

(2)空间大小不同

栈是向低地址扩展,是一块连续的内存区域.即栈顶的地址和栈的最大容量是系统预先规定好的,当申请的空间超过栈的剩余空间时,将出现栈溢出错误.堆是向高地址扩展,是不连续的内存区域.由于系统是用链表来存储空暇内存地址的。且链表的遍历方向是由低地址高地址.

(3)产生碎片不同

对于堆来说。频繁的malloc/free势必会造成内存空间的不连续从而造成大量的碎片,使程序效率减少.对于栈来说。一定是连续的物理内存空间.

(4)增长方式不同

在X86平台上,堆的增长方向是向上。即向着内存地址添加的方向。栈的增长方向是向下的,即向着内存地址减小的方向.

(5)分配方式不同

堆都是程序中由malloc()函数动态申请分配并由free() 函数释放。栈的分配和释放是由操作系统完毕的,栈的动态分配有alloca()函数完毕,可是栈的动态分配和堆是不同的,其由编译器进行分配和释放,无须手工完毕.

(6)分配效率不同

栈是系统提供的。操作系统会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都是专门的指令运行.堆则是C函数库提供的,它的机制非常复杂。比如为了分配一块内存,则须要操作系统又一次整理内存。搜索整理内存空间,这样就有机会分到足够大小的内存,然后返回.显然。堆的效率比栈要低的多.

笔者:个人能力有限,仅仅是学习參考...读者若发现文中错误,敬请提出.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------勿在浮沙筑高台。静下心来。慢慢地沉淀---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

时间: 2024-10-07 17:53:33

Linux程序存储结构与进程结构 堆和栈的差别的相关文章

Linux程序存储结构与进程结构 堆和栈的区别

摘要:本文主要讲述了Linux系统中,程序存储结构(代码区.数据段和BBS区)与进程的基本结构(代码区.数据段.BBS区.堆和栈),以及堆和栈的区别. Linux程序存储结构与进程结构 1.Linux程序存储结构 在Linux系统下,程序是一个普通的可执行文件,图1是一个Linux下ELF格式可执行文件的基本情况. 图1 ELF格式可执行文件的基本信息 可以看出,此ELF格式可执行文件在存储时,没有调入到内存,分为代码区(text),数据区(data)和为初始化区(bss)3个部分.各段基本说明

第二十一篇:Linux 操作系统中的进程结构

前言 在 Linux 中,一个正在执行的程序往往由各种各样的进程组成,这些进程除了父子关系,还有其他的关系.依赖于这些关系,所有进程构成一个整体,给用户提供完整的服务( 考虑到了终端,即与用户的交互 ). 本文将详细描述 Linux 中的进程结构. 进程结构 上图所描述的是为了给用户提供一次完整服务( 需要处理用户IO等 )所涉及到的一个完整的进程结构,几个部分解释如下: 1. 控制进程 建立与终端连接的进程称为控制进程( 属于后台进程组之一 ) 2. 前台进程组 控制终端( 处理如Ctrl+C

堆和栈的差别(转过无数次的文章)

一.预备知识—程序的内存分配    一个由C/C++编译的程序占用的内存分为下面几个部分    1.栈区(stack)—   由编译器自己主动分配释放   ,存放函数的參数值,局部变量的值等.其    操作方式相似于数据结构中的栈.    2.堆区(heap)   —   一般由程序猿分配释放,   若程序猿不释放,程序结束时可能由OS回    收   .注意它与数据结构中的堆是两回事,分配方式倒是相似于链表,呵呵.    3.全局区(静态区)(static)—,全局变量和静态变量的存储是放在一

Linux 可执行文件结构与进程结构

Linux可执行文件结构 在 Linux 下,程序是一个普通的可执行文件,以下列出一个二进制可执行文件的基本情况: 可以看出,此可执行文件在存储时(没有调入到内容)分为代码区(text).数据区(data)和未初始化数据区(bss)3 个部分.各段基本内容说明如下: 代码区: 存放 CPU 执行的机器指令.通常代码区是可共享的(即另外的执行程序可以调用它),使其可共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可.代码区通常是只读的,使其只读的原因是防止程序意外地修改了它的指令.另外

oracle进程结构简介

我们经常说数据库实例,实例其实就是指的是数据库的内存结构和进程结构.我们安装数据库软件大量的是在安装其内存和进程组件结构.上篇节我们介绍了oracle内存结构,这节就介绍下oracle进程结构. 首先看下oracle进程的分类: 1)用户进程 是连接到Oracle DB 的应用程序或工具 2)数据库进程 服务器进程:连接到Oracle实例,在用户建立会话时启动 后台进程:在启动Oracle实例时启动 3) 守护程序/应用程序进程 网络监听程序 Gridinfrastructure 守护程序 从进

Linux 程序设计学习笔记----进程管理与程序开发(上)

转载请注明出处,http://blog.csdn.net/suool/article/details/38406211,谢谢! Linux进程存储结构和进程结构 可执行文件结构 如下图: 可以看出,此ELF可执行文件存储时(没有调入内存)分为代码区.数据区和未出花数据区三部分. 代码区:存放cpu的执行的机器指令. 数据区:包含程序中的已经初始化的静态变量,以及已经初始化的全局变量. 未初始化数据区:存入的是未初始化的全局变量和未初始化的静态变量. 现在在上面的程序代码中增加一个int的静态变量

数据结构中的堆和栈 与 内存分配中的堆区和栈区 分析

比較全面的总结了诸多版本号,知识无国界.感谢各位的辛勤劳作. 在计算机领域,堆栈是一个不容忽视的概念,我们编写的C/C++语言程序基本上都要用到.但对于非常多的初学着来说,堆栈是一个非常模糊的概念. (1) 数据结构的栈和堆 首先在数据结构上要知道堆栈,虽然我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈. 堆和栈都是一种数据项按序排列的数据结构. 栈就像装数据的桶或箱子 我们先从大家比較熟悉的栈说起吧.它是一种具有后进先出性质的数据结构,也就是说后存放的先取.先存放的后取.这就如同我们要取出

Linux文件系统具有良好的结构,提供了很多文件处理程序,那么常用的文件处理命令有哪些?

本文标签:    Linux系统 Linux Linux文件系统 Linux入门 Linux常用命令 互联网杂谈 Linux系统信息存放在文件里,文件与普通的公务文件类似.每个文件都有自己的名字.内容.存放地址及其它一些管理信息,如文件的用户.文件的大小等.文件可以是一封信.一个通讯录,或者是程序的源语句.程序的数据,甚至可以包括可执行的程序和其它非正文内容.Linux文件系统具有良好的结构,系统提供了很多文件处理程序.这里主要介绍常用的文件处理命令. file 1.作用 file通过探测文件内

第5章 进程环境(1)_进程结构(task_struct)

1. 进程的概念和进程结构 1.1 进程 (1)程序(program):是一些保存在磁盘上有序指令的集合,是存放在磁盘文件中的可执行文件.但没有任何执行的概念,它是静态的. (2)进程(process) ①程序的执行实例被称为进程,是一个动态的概念,它是程序执行的过程,包括创建.调度和消亡. ②进程具有独立的权限与职责,如果系统中某个进程崩溃,它不会影响其余的进程. ③每个进程运行在其各自的虚拟地址空间中,进程之间可以通过由内核控制的机制相互通信. (3)进程ID:每个linux进程都有一个唯一