Chinaunix首页 | 论坛 | 博客
  • 博客访问: 334137
  • 博文数量: 80
  • 博客积分: 711
  • 博客等级: 上士
  • 技术积分: 733
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-23 15:43
文章分类

全部博文(80)

文章存档

2015年(9)

2014年(14)

2013年(33)

2012年(24)

我的朋友

分类: Java

2013-05-16 18:26:54

简单地说,堆就是由你自己管理,而栈是由系统管理

效率方面

1、内存分配方面:

    堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中堆是两回事,分配方式是类似于链表。可能用到关键字如下:new、malloc、delete、free等等。

    栈:由编译器(Compiler)自动分配释放,存放函数参数值,局部变量值等。其操作方式类似于数据结构中栈。

2、申请方式方面:

    堆:需要程序员自己申请,并指明大小。在c中malloc函数如p1 = (char *)malloc(10);在C++中用new运算符,但是注意p1、p2本身是在栈中。因为他们还是可以认为是局部变量。

    栈:由系统自动分配。 例如,声明在函数中一个局部变量 int b;系统自动在栈中为b开辟空间。

3、系统响应方面:

    堆:操作系统有一个记录空闲内存地址链表,当系统收到程序申请时,会遍历该链表,寻找第一个空间大于所申请空间堆结点,然后将该结点从空闲结点链表中删除,并将该结点空间分配给程序,另外,对于大多数系统,会在这块内存空间中首地址处记录本次分配大小,这样代码中delete语句才能正确释放本内存空间。另外由于找到堆结点大小不一定正好等于申请大小,系统会自动将多余那部分重新放入空闲链表中。

    栈:只要栈剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

4、大小限制方面:

    堆:是向高地址扩展数据结构,是不连续内存区域。这是由于系统是用链表来存储空闲内存地址,自然是不连续,而链表遍历方向是由低地址向高地址。堆大小受限于计算机系统中有效虚拟内存。由此可见,堆获得空间比较灵活,也比较大。

    栈:在Windows下, 栈是向低地址扩展数据结构,是一块连续内存区域。这句话意思是栈顶地址和栈最大容量是系统预先规定好,在WINDOWS下,栈大小是固定(是一个编译时就确定常数),如果申请空间超过栈剩余空间时,将提示overflow。因此,能从栈获得空间较小。

5、效率方面:

    堆:是由new分配内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便,另外,在WINDOWS下,最好方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

    栈:由系统自动分配,速度较快。但程序员是无法控制。

6、存放内容方面:

    堆:一般是在堆头部用一个字节存放堆大小。堆中具体内容有程序员安排。

    栈:在函数调用时第一个进栈是主函数中后下一条指令(函数调用语句下一条可执行语句)地址然后是函数各个参数,在大多数C编译器中,参数是由右往左入栈,然后是函数中局部变量。 注意: 静态变量是不入栈。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存地址,也就是主函数中下一条指令,程序由该点继续运行。

7、存取效率方面:

    堆:char *s1 = "Hellow Word";是在编译时就确定;

    栈:char s1[] = "Hellow Word"; 是在运行时赋值;用数组比用指针速度要快一些,因为指针在底层汇编中需要用edx寄存器中转一下,而数组在栈上直接读取。

阅读(868) | 评论(0) | 转发(0) |
0

上一篇:Java-Regex

下一篇:Android签名与签名校验

给主人留下些什么吧!~~