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

三种内存分配模式

阅读更多

系统为进程分配数据空间有三种形式。

静态分配

整块静态分配空间,包括其中的所有数据实体,都是在进程创建时由系统一次性分配的(同时为UNIX称为Text的代码分配空间)。这块空间在进程运行期间保持不变。

初始化的和未初始化的实体分别放在初始化数据段和未初始化数据段(BSS)。后者和前者不同,在.o文件a.out文件里都不存在(只有构架信息),在进程的虚拟空间里才展开。

extern变量和static变量采用静态分配。

在进程创建时做静态分配,分配正文(text)段、数据段和栈空间。

正文和初始化数据是按a.out照样复制过来;未初始化数据按构架信息展开,填以0或空;栈空间的大小由链接器开关(具体哪个开关忘了)决定。

栈分配

整个栈空间已在进程创建时分配好。栈指针SP的初值的设定,确定了栈空间的大小。链接器的某个开关可以设定栈空间的大小。在进程运行期间,栈空间的大小不变。但是,在进程刚启动时,栈空间是空的,里面没有实体。在进程运行期间,对具体实体的栈分配是进程自行生成(压栈)和释放(弹出)实体,系统并不参与。

auto变量和函数参数采用栈分配。

只要压入的实体的总长度不超过栈空间尺寸,栈分配就与系统无关。如果超过了,就会引发栈溢出错误。

堆分配

当进程需要生成实体时,向系统申请分配空间;不再需要该实体时,可以向系统申请回收这块空间。

堆分配使用特定的函数(如malloc()等)或操作符(new)。所生成的实体都是匿名的,只能通过指针去访问。

对实体来说,栈分配和堆分配都是动态分配:实体都是在进程运行中生成和消失。而静态分配的所有实体都是在进程创建时全部分配好的,在运行中一直存在。

同 为动态分配,栈分配与堆分配是很不相同的。前者是在进程创建时由系统分配整块栈空间,以后实体通过压栈的方式产生,并通过弹出的方式取消。不管是否产生实 体,产生多少实体,栈空间总是保持原来的大小。后者并没有预设的空间,当需要产生实体时,才向系统申请正好能容纳这个实体的空间。当不再需要该实体时,可 以向系统申请回收这块空间。因此,堆分配是真正的动态分配。

显然,堆分配的空间利用率最高。

栈分配和静态分配也有共性:整块空间是在进程创建时由系统分配的。但是,后者同时分配了所有实体的空间,而前者在进程启动时是空的。另外,栈上的实体和数据段里的实体都是有名实体,可以通过标识符来访问。
静态分配 栈分配 堆分配
整块空间生成 进程创建时 进程创建时 用一点分配一点
实体生成时间 进程创建时 进程运行时 进程运行时
实体生成者 操作系统 进程 进程申请/系统实施
生命期 永久 临时 完全可控
有名/匿名 有名 有名 匿名
访问方式 能以标识访问 能以标识访问 只能通过指针访问
空间可否回收 不可 不可 可以
分享到:
评论

相关推荐

    内存分配顺序和大小端模式

    c++程序源文件, 判断内存分配顺序和大小端模式

    论文研究-WDF下用户模式和内核模式之间的内存共享 .pdf

    WDF下用户模式和内核模式之间的内存共享,张奇,谢军,Windows Driver Foundation (WDF) 是用于开发Windows 驱动程序的全新平台,也是微软推出的下一代的驱动开发模式。本文简单介绍了该平台下的一��

    一种高效的C++固定内存块分配器

    取决于内存分配的模式和堆内存的实现方式,长时间的使用堆内存可能导致堆内存错误。典型的解决方案是预先静态声明所有对象的内存,从而摆脱动态申请内存。然而,由于对象即使没有被使用,也已经存在并占据一部分内存...

    内存管理内存管理内存管理

    程序的动态性越强,内存管理就越重要,您的内存分配程序的选择也就更重要。让我们来了解可用于内存管理的不同方法,它们的好处与不足,以及它们最适用的情形。 C 风格的内存分配程序 C 编程语言提供了两个函数来...

    spark:Executor分配详解

    用户应用new SparkContext后,集群就会为在Worker上分配executor,但是增加executor的时候需要考虑好内存消耗,因为一台机器的内存分配给越多的executor,每个executor的内存就越小,以致出现过多的数据spill over...

    C#23种设计模式_示例源代码及PDF

    享元模式大幅度 的降低内存中对象的数量。 12、PROXY —跟 MM 在网上聊天,一开头总是“hi,你好”,“你从哪儿来呀?”“你多大了?”“身 、 高多少呀?”这些话,真烦人,写个程序做为我的 Proxy 吧,凡是接收...

    glibc内存管理ptmalloc源代码分析

    2.2 操作系统内存分配的相关函数 2.2.1 Heap操作相关函数 2.2.2 Mmap映射区域操作相关函数 3. 概述 3.1 内存管理一般性描述 3.1.1 内存管理的方法 3.1.2 内存管理器的设计目标 3.1.3 常见C内存管理程序 3.2 ...

    游戏画面就弹出内存不能为read修复工具

    先说原理:内存有个存放数据的地方叫缓冲区,当程序把数据放在缓冲区,需要操作系统提供的“功能函数”来申请,如果内存分配成功,函数就会将所新开辟的内存区地址返回给应用程序,应用程序就可以通过这个地址使用...

    模拟系统动态分配内存(含源代码)

    模拟示例了系统动态分配内存的方法和模式,代码简单,可用于初学者学习之用

    操作系统(内存管理)

    因此,当加载一个进程时,它会得到一个取决于某个称为 系统中断点(system break)的特定地址的初始内存分配。该地址之后是未被映射的内存 —— 用于在 RAM 或者硬盘中没有分配相应物理位置的内存。因此,如果一个...

    图解Java单例模式内存分配

    1:虚拟机加载StaticDemo类,保存类型信息到方法区。  2:通过保存在方法区的字节码,虚拟机开始main方法,main方法入栈。  3:进入main方法第一条指令,Person.getInstance();首先虚拟机加载Person类到方法区...

    线程,进程,内存分配以及工作站模式与服务器模式

    您可能没有意识到的有关内存分配和线程的知识,还有一个鲜为人知的东西,称为“服务器模式”

    软件设计模式——享元模式设计报告

    但同口味的咖啡的配料表中有着相同的基础配料即对象有相同的变量,如果给这些相同的变量也一一分配内存,将会造成大量的内存浪费。如果利用享元模式将相同的变量封装到一起成为供其他对象共享的享元,这样便可以节省...

    0x00000000内存不能为read修复工具

    程序需要一块内存用以保存数据时,就需要调用操作系统提供的“功能函数”来申请,如果内存分配成 功,函数就会将所新开辟的内存区地址返回给应用程序,应用程序就可以通过这个地址使用这块内存。这 就是“动态内存...

    alloc-effect-checker:Java 内存分配检查器

    分配效果检查器在 Java 中强制执行内存分配模式的效果系统。 使用。 系统要求Java 8 或 JSR 308 注释工具(可在 Checker Framework 网站上找到) 这个怎么运作检查器定义了两个方法注释@MayAlloc和@NoAlloc ,它们...

    linux下检测内存泄漏

    在 windows 下使用 VC 编程时,我们通常需要 DEBUG 模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名、行号以及内存大小。该功能是 MFC ...

    scratchpad:Rust库提供具有双端分配支持的类似堆栈的内存分配器

    便笺Rust库提供具有双端分配支持的类似堆栈的内存分配器。注意: scratchpad目前处于维护模式。 我一直在考虑进行大型清理,以消除多余的功能并减少unsafe代码的表面积,但是目前尚无时间表。 我仍然会根据需要应用...

    Visual C++内存泄露检测工具

    相比Visual C++自带的内存检测机制,Visual Leak Detector可以显示导致内存泄露的完整内存分配调用堆栈。 下载Visual Leak Detector,当前版本2.2.3,在Visual C++ IDE的"工具"→"选项"→"项目和解决方案"→"VC++ ...

    OdinMemoryAllocator:一个便携式内存分配器,旨在尽可能减少外部碎片

    这个内存分配器是我在业余时间工作的名为 Odin 的游戏引擎的一部分。 此分配器旨在跨平台移植,并通过根据使用模式分解分配来尽可能地减少碎片。 设计的某些部分是从其他关于游戏引擎(如 MolecularEngine 和 ...

Global site tag (gtag.js) - Google Analytics