栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

堆和栈的区别

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

堆和栈的区别

参考链接:difference between stack and heap

目录

内存管理

堆和栈的区别

Stack

Heap


内存管理

对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。

C++中,内存分为5个区:堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区。通常存放局部变量、函数参数等。

堆:是由new分配的内存块,由程序员释放(编译器不管),一般一个new与一个delete对应,一个new[]与一个delete[]对应。如果程序员没有释放掉, 资源将由操作系统在程序结束后自动回收。

自由存储区:是由malloc等分配的内存块,和堆十分相似,用free来释放。

全局/静态存储区:全局变量和静态变量被分配到同一块内存中(在C语言中,全局变量又分为初始化的和未初始化的,C++中没有这一区分)。

常量存储区:这是一块特殊存储区,里边存放常量,不允许修改。

//main.cpp
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)    // 分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456");        // 123456/0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
├———————┤低端内存区域
│ …… │
├———————┤
│ 动态数据区 │
├———————┤
│ …… │
├———————┤
│ 代码区 │
├———————┤
│ 静态数据区 │
├———————┤
│ …… │
├———————┤高端内存区域

堆和栈的区别

Stack
  • stack involves linear and sequential allocation of the memory;
  • LIFO先进后出,具有2个指针分别指向first entry和last entry。
  • fucntion calls。一个function call可以hold一些stack enrty的集合,也叫做stack frame。当function call 发生时,stack frame会被push进stack。(进栈)
  • 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
  • allocation 和deallocation is finshed by CPU
  • 申请时:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
  • 大小限制:1M OR 2M?
  • 生长方向:向高地址
  • 栈有静态分配和动态分配,静态分配由编译器完成(如局部变量分配),动态分配由alloca函数 分 配,但栈的动态分配的资源由编译器进行释放,无需程序员实现。
  • 如果function调用结束,对应的stack frame will be gone

Heap
  • heaps act as a pool of storage are that allocated the memory randomly (Dynamic)
  • 一个分配请求会被返回一个pointer to the allocated memory。
  • deallocation需要程序员手动完成
  • A function call in stack takes O(N) time. In contrast, it takes O(1) time in a heap.
  • 申请时:操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
  • 堆大小受限于计算机系统中有效的虚拟内存(32bit 系统理论上是4G),由此可见,堆获得的空间比较灵活,也比较大。
  • 生长方向:向低地址
  • 堆都是动态分配
  • 可以在thread之间共享

 

不同类型数据的存储地址:

#include 
int g1=0, g2=0, g3=0;
int main()
{
    static int s1=0, s2=0, s3=0;
    int v1=0, v2=0, v3=0;
    //打印出各个变量的内存地址    
    printf("0x%08xn",&v1); //打印各本地变量的内存地址
    printf("0x%08xn",&v2);
    printf("0x%08xnn",&v3);
    printf("0x%08xn",&g1); //打印各全局变量的内存地址
    printf("0x%08xn",&g2);
    printf("0x%08xnn",&g3);
    printf("0x%08xn",&s1); //打印各静态变量的内存地址
    printf("0x%08xn",&s2);
    printf("0x%08xnn",&s3);
    return 0;
}

结果:

0x005ffd74
0x005ffd68
0x005ffd5c

0x002d070c
0x002d0710
0x002d0714

0x002d0718
0x002d071c
0x002d0720

全局变量和静态变量分配的内存是连续的。这是因为本地变量和全局/静态变量是分配在不同类型的内存区域中的结果。

函数调用

#include 
void __stdcall func(int param1,int param2,int param3)
{
    int var1=param1;
    int var2=param2;
    int var3=param3;
    printf("0x%08xn",param1); //打印出各个变量的内存地址
    printf("0x%08xn",param2);
    printf("0x%08xnn",param3);
    printf("0x%08xn",&var1);
    printf("0x%08xn",&var2);
    printf("0x%08xnn",&var3);
    return;
}
 
int main() {
    func(1,2,3);
    return 0;
}
0x0012ff78
0x0012ff7c
0x0012ff80
 
0x0012ff68
0x0012ff6c
0x0012ff70
├———————┤<—函数执行时的栈顶TOP(ESP)、低端内存区域
│ …… │
├———————┤
│ var 1 │
├———————┤
│ var 2 │
├———————┤
│ var 3 │
├———————┤
│ RET │
├———————┤<—“__cdecl”函数返回后的栈顶(ESP)
│ parameter 1 │
├———————┤
│ parameter 2 │
├———————┤
│ parameter 3 │
├———————┤<—“__stdcall”函数返回后的栈顶(ESP)
│ …… │
├———————┤<—栈底BOTTOM(基地址 EBP)、高端内存区域

参考:

函数调用过程:3个参数按照从右到左的顺序压入栈,然后param3 param2 param1,然后压入函数的返回地址(RET)。

e.g.堆栈上的变量

	int x = 1;
	int y = 1;
	int* hx = new int(1);

	cout << "address of x:" << &x < 

结果为:

address of x:004FFC04
address of y:004FFBF8
address of hx:004FFBEC
hx:00961F90
*hx:1

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1002609.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号