首页 > 其他分享 >前端 堆、栈 概念和区别

前端 堆、栈 概念和区别

时间:2022-11-22 10:15:20浏览次数:47  
标签:函数 区别 前端 概念 存放 内存 拷贝 分配 操作系统

1. 概念

  栈:先进后出,由操作系统自动分配释放,存放函数的参数值、局部变量值等。其操作方式类似于数据结构中的栈;是一种运算受限的线性表;

  堆:先进先出,动态分配的空间一般由程序员来分配释放,若不主动释放,程序结束由系统回收,分配方式类似于链表;是一个特定的存储区或寄存器,他的一端是固定的,另一端是浮动的。

 

2. 区别

  堆和栈实际是操作系统对进程占用的内存空间的两种管理方式,主要有一下几种区别:

  (1)管理方式不同

    栈:由操作系统自动分配释放,不需要我们控制
    堆:由程序员控制申请和释放,容易产生内存泄漏

  (2)空间大小不同,每个进程中栈的大小要远远小于堆的大小

    栈:windows64位1M,linux默认10M

    堆:理论上,程序员申请的堆大小为虚拟内存的大小

  (3)生长方向不同

    栈:生长方向向下,内存地址由高到低,仅在表尾(栈顶)进行插入和删除操作的线性表,另一端是栈底;按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的在栈顶,需要读取数据时从栈顶开始弹出数据;

    堆:生长方向向上,内存地址由低到高,

  (4)分配方式不同

    栈:有两种分配方式,静态分配和动态分配;

      静态分配:由操作系统完成的,比如局部变量的分配

      动态分配:由alloca函数进行分配,由操作系统进行释放,与堆的不同

    堆:都是动态分配的,没有静态分配的堆

  (5)分配效率不同

    栈:由操作系统自动分配,会在硬件层级对栈提供支持;分配专门的寄存器存放栈的地址,压栈出栈都有专门的执行指令,这就决定了栈的效率比较高;

    堆:由C/C++提供的库函数或运算符来完成申请和管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片,显然,堆的效率比栈要低得多;

  (6)存放内容不同

    栈:函数返回地址、相关参数、局部变量和寄存器内容等。当主函数调用另外函数时,要对当前函数执行断点进行保存,需要使栈来实现。首先入栈的是主函数下一条语句的地址,即扩展指针寄存器的内容(EIP),然后是当前栈帧的底部地址,即扩展基址指针寄存器内容(EBP),再然后是被调函数的实参等,一般情况下是按照从右向左的顺序入栈,之后是被调函数的局部变量,注意静态变量是存放在数据段或者BSS段,是不入栈的。出栈的顺序正好相反,最终栈顶指向主函数下一条语句的地址,主程序又从该地址开始执行。

    堆:一般情况下,堆顶使用一个字节来存放堆的大小,而堆中具体存放的内容是由程序员来填充的;

3. 总结:

    综上,可以看出堆和栈相比,由于大量的malloc()/free()或new/delete的使用,容易造成大量的内存碎片,并且可能引发用户态和核心态的切换,效率较低。

    栈相比于堆,在程序中应用较为广泛,最常见的是函数的调用过程由栈来实现,函数返回地址、EBP、实参和局部变量都是采用栈的方式存放,虽然栈有众多的好处,但是由于和堆比不是那么的灵活,有的时候分配大量的空间,还是用堆。

    无论是堆还是栈,在内存使用中都要防止非法越界,越界导致的非法内存访问可能会摧毁程序的堆、栈数据,轻则导致程序的运行处于不确定状态,获取不到预期结果,重则导致程序一场崩溃,这些都是我们编程时与内存打交道时应该注意的问题。

 

 

前端相关

javascript 数据分为两大类: 基本类型、引用类型

1. 基本类型:null、undefined、Number、String、Boolean,ES6还新增了一种Symbol

  基本数据类型可以直接访问,他们是按照值进行分配的,存放在栈(stack)中的简单数据段,数据大小不确定,内存空间大小可以分配。  

2. 引用类型:及Object,是存放在堆(heap)内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。

 

扩展:说到堆栈内存,自然就会涉及到闭包、浅拷贝、深拷贝,还有call、bind、apple

(1)浅拷贝和深拷贝,只有引用类型才有浅拷贝、深拷贝这么一说,基本数据类型没有

  最常用的深拷贝方法:序列法和反序列法

const deepClone = (obj) => {
  return JSON.parse(JSON.stringify(obj))
}

标签:函数,区别,前端,概念,存放,内存,拷贝,分配,操作系统
From: https://www.cnblogs.com/liql/p/16914216.html

相关文章

  • 推荐一款高效率前端开发神器,功能太强大了 !
    当前端收到一张设计稿的时候,他们需要考虑非常多的问题。而第一个摆在面前的问题就是- ​​切图​​。作为连接设计师和前端的重要“纽带”,如果切图不准确,很容易导致最终的......
  • 前端工程化 - 剖析npm的包管理机制
    导读现如今,前端开发的同学已经离不开 npm 这个包管理工具,其优秀的包版本管理机制承载了整个繁荣发展的NodeJS社区,理解其内部机制非常有利于加深我们对模块开发的理解、......
  • 依据前端返回参数,动态构建lambda表达式
    1、构建前端返回类///<summary>///查询明细///</summary>publicclassQueryItem{///<summary>///查询项字段///......
  • React类式组件和函数式组件的区别
    React类式组件和函数式组件的区别有哪些呢?  主要要以下几个区别:(1)语法不同、设计思想不同(2)生命周期、状态变量(3)复用性:(4)优缺点一、语法不同、设计思想不同函数式组件......
  • 前端-git命令
    git工作流:Git工作流指南:Gitflow工作流-久依-博客园(cnblogs.com)#**Git-常用**###常用操作```#拉取仓库代码[email protected]:xlPay/XL......
  • MDH 前端周刊第 77 期:布局动画、Arrow JS、vanilla-extract、antd 5、dumi 2
    MDH前端周刊第77期:布局动画、ArrowJS、vanilla-extract、antd5、dumi2原创 云谦 云谦和他的朋友们 2022-11-2109:25 发表于浙江收录于合集#MDH:前端周刊81个......
  • 【前端】JS去重
     /**JSON数组去重*@param:[array]jsonArray*@param:[string]唯一的key名,根据此键名进行去重*/exportconstuniqueArray=(array,key)=>{varres......
  • ArrayList和LinkedList的区别和使用场景
    先看看接口关系1.ArrayList和LinkedList区别ArrayList是对象数组实现的,LinkedListed是基于双链表实现的。LinkedList的存储消耗较大,除了存储数据外还要有上下节点的......
  • MySQL_连接时where和and的区别
    内连接是从结果表中删除与其他被连接表中没有匹配行的所有行,on和where的效果一致 左外连接(on先执行,where后执行)and条件是在生成临时表时使用的条件,它不管on中的条件是......
  • 图文并茂解释开源许可证 GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    什么是开源许可证?(“OpenSourceLicense”) 首先需要明确的是,开源软件源代码的著作权既没有被放弃也没有过期,其修改和发行等仍然要受到著作权法或者开源软件许可证的制......