在.NET程序运行过程中,什么是堆,什么是栈

在.NET程序运行过程中,什么是堆,什么是栈,第1张

栈和堆的区别

堆栈空间分配

栈( *** 作系统):由 *** 作系统自动分配释放,存放函数的变量值,局部变量的值等等,其 *** 作方式类似于数据结构中的栈;

堆( *** 作系统):一般由开发者分配释放,若不释放,程序结束时可能会有OS回收,分配方式倒是类似于链表;

堆栈的缓存方式

栈使用的是一级缓存,通常是被调用时处于储存空间,调用完后自动释放;

堆使用的是二级缓存,生命周期有虚拟机的垃圾回收算法来决定(并不一定成为孤儿对象就被立即释放)。所以调用这些对象的速度相对来得慢一些;

堆栈数据结构的区别

堆(数据结构):堆可以看做是一棵树;例如:堆排序;

栈(数据结构):一种先进后出的数据结构;

区别介绍

栈负责保存我们的代码执行(或调用)路,而堆则负责保存对象(或者说数据)的路径。

可以将栈想象成一堆从顶向下堆叠的盒子。当每调用一次方法时,我们将应用程序中所要发生的事情记录在栈顶的一个盒子中,而我们每次只能够使用栈顶的那个盒子。当我们栈顶的盒子被使用完之后,或者说方法执行完毕之后,我们将抛开这个盒子然后继续使用栈顶上的新盒子。堆的工作原理比较相似,但大多数时候堆用作保存信息而非保存执行路径,因此堆能够在任意时间被访问。与栈相比堆没有任何访问限制,堆就像床上的旧衣服,我们并没有花时间去整理,那是因为可以随时找到一件我们需要的衣服,而栈就像储物柜里堆叠的鞋盒,我们只能从最顶层的盒子开始取,直到发现那只合适的。

以上并不是内存中真实的表现形式,但能够帮助我们区分栈和堆。

栈是自行维护的,也就是说内存自动维护栈,当栈顶的盒子不再被使用,它将被抛出。相反的,堆需要考虑垃圾回收,垃圾回收用于保持堆的整洁性,没有人愿意看到周围都是赃衣服,那简直太臭了!

当我们的代码执行的时候,栈和堆中主要放置了四种类型的数据:值类型(Value Type),引用类型(Reference Type),指针(Pointer),指令(Instruction)。

1值类型

bool,byte ,char,decimal,double,enum,float,int,long,sbyte,short,struct,uint,ulong,ushort

2引用类型

class,interface,delegate ,object ,string

3指针

在内存管理方案中放置的第三种类型是类型引用,引用通常就是一个指针。我们不会显示的使用指针,它们由公共语言运行时(CLR)来管理。指针(或引用)是不同于引用类型的,是因为当我们说某个事物是一个引用类型时就意味着我们是通过指针来访问它的。指针是一块内存空间,而它指向另一个内存空间。就像栈和堆一样,指针也同样要占用内存空间,但它的值是一个内存地址或者为空。

先从大家比较熟悉的栈说起,它是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取。这就如同要取出放在箱子里面底下的东西(放入的比较早的物体),首先要移开压在它上面的物体(放入的比较晚的物体)。而堆就不同了,堆是一种经过排序的树形数据结构,每个结点都有一个值。通常所说的堆的数据结构,是指二叉堆。堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆。由于堆的这个特性,常用来实现优先队列,堆的存取是随意,这就如同在图书馆的书架上取书,虽然书的摆放是有顺序的,但是想取任意一本时不必像栈一样,先取出前面所有的书,书架这种机制不同于箱子,可以直接取出想要的书。

下面就说说C语言程序内存分配中的堆和栈,这里有必要把内存分配也提一下,一般情况下程序存放在Rom或Flash中,运行时需要拷到内存中执行,内存会分别存储不同的信息。

内存中的栈区处于相对较高的地址以地址的增长方向为上的话,栈地址是向下增长的,栈中分配局部变量空间,堆区是向上增长的用于分配程序员申请的内存空间。另外还有静态区是分配静态变量,全局变量空间的;只读区是分配常量和程序代码空间的;以及其他一些分区。来看一个网上很流行的经典例子:

maincpp

int a = 0; 全局初始化区

char p1; 全局未初始化区

main()

{

int b; 栈

char s[] = "abc"; 栈

char p2; 栈

char p3 = "123456"; 123456\0在常量区,p3在栈上。

static int c =0; 全局(静态)初始化区

p1 = (char )malloc(10); 堆

p2 = (char )malloc(20); 堆

}

堆和栈的第一个区别就是申请方式不同:栈(英文名称是stack)是系统自动分配空间的,例如定义一个 char a;系统会自动在栈上为其开辟空间。而堆(英文名称是heap)则是程序员根据需要自己申请的空间,例如malloc(10);开辟十个字节的空间。由于栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。而堆上的数据只要程序员不释放空间,就一直可以访问到,不过缺点是一旦忘记释放会造成内存泄露。

堆栈是一种执行“后进先出”算法的数据结构。

设想有一个直径不大、一端开口一端封闭的竹筒。有若干个写有编号的小球,小球的直径比竹筒的直径略小。现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来。所以“先进后出”就是这种结构的特点。

堆栈就是这样一种数据结构。它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中。有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫做堆栈指示器。开始放入数据的单元叫做“栈底”。数据一个一个地存入,这个过程叫做“压栈”。在压栈的过程中,每有一个数据压入堆栈,就放在和前一个单元相连的后面一个单元中,堆栈指示器中的地址自动加1。读取这些数据时,按照堆栈指示器中的地址读取数据,堆栈指示器中的地址数自动减 1。这个过程叫做“d出pop”。如此就实现了后进先出的原则。

堆栈是计算机中最常用的一种数据结构,比如函数的调用在计算机中是用堆栈实现的。

堆栈可以用数组存储,也可以用以后会介绍的链表存储。

下面是一个堆栈的结构体定义,包括一个栈顶指针,一个数据项数组。栈顶指针最开始指向-1,然后存入数据时,栈顶指针加1,取出数据后,栈顶指针减1。

#define MAX_SIZE 100

typedef int DATA_TYPE;

struct stack

{

DATA_TYPE data[MAX_SIZE];

int top;

};

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后, *** 作系统会自动回收。

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多

堆栈是计算机为程序分配的内存空间,用来存储数据的。

内存是计算机系统中一个主要部件, 用于保存进程运行时的程序和数据,也称可执行存储器。在计算机中,内存空间一般是指主存储器空间(物理地址空间)或系统为一个用户程序分配内存空间。扩展内存空间的方法一般有增加内存大小和虚拟内存。

源程序经过汇编或编译后再经过链接编辑程序加工形成的程序的装配模块,及转换为相对地址编址的模块,它是以0为基址顺序进行编址的。

相对地址也称为逻辑地址或虚拟地址,把程序中由相对地址组成的空间叫做逻辑地址空间。相对地址空间通过地址再定位机构转换到绝对地址空间,绝对地址空间也叫物理地址空间。

内存空间一般是指主存储器空间(物理地址空间)或系统为一个用户程序分配内存空间。系统为一个用户程序分配内存空间方法有单一连续分配、固定分区分配、动态分区分配以及动态重定位分区分配四种方式。

为了便于内存分配,通常将分区按大小进行排队,并为之建立一张分区使用表,其中各表项包括每个分区的起始地址、大小及状态(是否已分配)。

当有一用户程序要装入时,由内存分配程序检索该表,从中找出一个能满足要求的、尚未分配的分区,将之分配给该程序,然后将该表项中的状态置为“已分配” ;若未找到大小足够的分区,则拒绝为该用户程序分配内存。

以上就是关于在.NET程序运行过程中,什么是堆,什么是栈全部的内容,包括:在.NET程序运行过程中,什么是堆,什么是栈、C程序中如何使用堆栈、软件中的 栈 是什么意思栈 是什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9849355.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存