image-20240420163459407

堆和栈

1. 堆和栈的概念

堆和栈是计算机内存中的两种数据存储区域,用于存储程序运行时的数据。堆和栈的区别主要体现在以下几个方面:

  1. 分配方式:堆是动态分配的,栈是静态分配的。
  2. 空间大小:堆的空间较大,栈的空间较小。
  3. 管理方式:堆需要手动管理内存,栈由系统自动管理。
  4. 分配效率:堆的分配效率较低,栈的分配效率较高。
    • 堆的分配效率较低是因为堆是不连续分配的,需要维护一个空闲内存链表,查找合适的空闲内存块。而且存在间接访问的开销。空间局部性较差,容易产生碎片。
  5. 存储方式:堆存储的是对象的引用,栈存储的是对象的值。
  6. 生命周期:堆的生命周期由程序员控制,栈的生命周期由系统控制。
  7. 存储内容:堆存储的是动态分配的对象,栈存储的是局部变量和函数参数。

2. 堆和栈的区别

  1. 栈是从高地址向低地址增长的,堆是从低地址向高地址增长的。
  2. 栈的分配速度比堆快,因为栈是连续分配的,而堆是不连续分配的
  3. 栈的分配和释放由系统自动管理,堆的分配和释放由程序员手动管理。
  4. 栈的空间有限,堆的空间较大。

3. 申请后系统的处理

  1. 栈:系统会自动分配和释放栈空间,当函数调用结束时,系统会自动释放栈空间,恢复上一层函数的执行。如果栈空间不足,会导致栈溢出。
  2. 堆:操作系统会维护一个记录空闲内存地址的链表,当程序申请内存时,系统会在链表中查找合适的空闲内存块,并返回给程序。程序员需要手动释放不再使用的内存,否则会导致内存泄漏。对于大多数操作系统,会在这块内存的头部和尾部加上一些额外的信息,用于记录这块内存的大小、是否被占用等信息。方便系统进行内存管理。

4. 申请大小限制

  1. 栈:栈的大小是有限的,通常在几MB到几十MB之间,具体取决于操作系统的设置。如果栈空间不足,会导致栈溢出。
  2. 堆:堆的大小通常比栈大得多,可以达到几GB。堆的大小受限于操作系统的虚拟内存大小,当虚拟内存耗尽时,会导致内存分配失败。

4. 堆和栈的应用

  1. 堆的应用
    • 动态内存分配:堆可以动态分配内存,用于存储动态数据结构,如链表、树等。
    • 垃圾回收:堆中的内存需要手动管理,程序员需要负责释放不再使用的内存,否则会导致内存泄漏。
    • 大对象存储:堆的空间较大,适合存储大对象,如大数组、大字符串等。
  2. 栈的应用
    • 函数调用:栈用于存储函数的参数、局部变量和返回地址,用于实现函数的调用和返回。
    • 递归调用:栈用于存储递归函数的调用信息,保证递归函数的正确执行。
    • 缓存数据:栈的空间较小,适合存储临时数据,如临时变量、中间结果等。

1.注意深拷贝和浅拷贝的区别,深拷贝是指在堆中重新分配一块内存,将原对象的内容复制到新的内存中,而浅拷贝只是复制了对象的引用,两个对象共享同一块内存。深拷贝需要手动实现,浅拷贝可以通过系统提供的拷贝构造函数或赋值运算符实现。