当前位置: 首页 > news >正文

前端高频面试题 js中堆和栈的区别和浏览器的垃圾回收机制

一、 栈(stack)和 堆(heap)

栈(stack):是栈内存的简称,栈是自动分配相对固定大小的内存空间,并由系统自动释放,栈数据结构遵循FILO(first in last out)先进后出的原则,较为经典的就是乒乓球盒结构,先放进去的乒乓球只能最后取出来。
在这里插入图片描述
堆(heap):是堆内存的简称,堆是动态分配内存,内存大小不固定,也不会自动释放,堆数据结构是一种无序的树状结构,同时它还满足key-value键值对的存储方式;我们只用知道key名,就能通过key查找到对应的value。比较经典的就是书架存书的例子,我们知道书名,就可以找到对应的书籍。
在这里插入图片描述
栈的特点:开口向上、速度快,容量小;堆的特点:速度稍慢、容量比较大;
在这里插入图片描述

二、 基本类型和引用类型

在这里插入图片描述
基本数据类型:Undefined,String,Boolean,Null,Number,都是直接按值存放在栈内存中,占用的内存空间的大小是确定的,并由系统自动分配和自动释放。这样带来的好处就是,内存可以及时得到回收,相对于堆来说,更加容易管理内存空间。
引用数据类型:指那些可能由多个值构成的对象,如对象(Object)、数组(Array)、函数(Function) ,它们是通过拷贝和new出来的,这样的数据存储于堆中。

三、 传值和传址的区别

基本类型:采用的是值传递。
引用类型:则是地址传递。

引用类型的数据的地址指针是存储于栈中的,将存放在栈内存中的地址赋值给接收的变量。当我们想要访问引用类型的值的时候,需要先从栈中获得对象的地址指针,然后,在通过地址指针找到堆中的所需要的数据(保存在堆内存中,包含引用类型的变量实际上保存的不是变量本身,而是指向该对象的指针)。

四、 内存分配垃圾回收

1.内存分配
(1)栈内存:线性有序存储,容量小,系统分配效率高。
(2)堆内存:首先要在堆内存新分配存储区域,之后又要把指针存储到栈内存中,效率相对就要低一些了。

2.垃圾回收:
(1)栈内存:变量基本上用完就回收了,相比于堆来说存取速度会快,并且栈内存中的数据是可以共享的。
(2)堆内存:堆内存中的对象不会随方法的结束而销毁,就算方法结束了,这个对象也可能会被其他引用变量所引用(参数传递)。创建对象是为了反复利用(因为对象的创建成本通常较大),这个对象将被保存到运行时数据区(也就是堆内存)。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

五、浏览器垃圾回收机制

1. 浏览器的垃圾回收机制

(1). 垃圾回收的概念
垃圾回收:JavaScript代码运⾏时,需要分配内存空间来储存变量和值。当变量不在参与运⾏时,就需要系统收回被占⽤的内存空间,这就是垃圾回收。

回收机制:
● Javascript 具有⾃动垃圾回收机制,会定期对那些不再使⽤的变量、对象所占⽤的内存进⾏释放,原理就是找到不再使⽤的变量,然后释放掉其占⽤的内存。
● JavaScript中存在两种变量:局部变量和全局变量。全局变量的⽣命周期会持续要⻚⾯卸载;⽽局部变量声明在函数中,它的⽣命周期从函数执⾏开始,直到函数执⾏结束,在这个过程中,局部变量会在堆或栈中存储它们的值,当函数执⾏结束后,这些局部变量不再被使⽤,它们所占有的空间就会被释放。
● 不过,当局部变量被外部函数使⽤时,其中⼀种情况就是闭包,在函数执⾏结束后,函数外部的变量依然指向函数内部的局部变量,此时局部变量依然在被使⽤,所以不会回收。

(3) 垃圾回收的⽅式
浏览器通常使⽤的垃圾回收⽅法有两种:标记清除,引⽤计数。
(1)标记清除

● 标记清除是浏览器常⻅的垃圾回收⽅式,当变量进⼊执⾏环境时,就标记这个变量“进⼊环境”,被标记为“进⼊环境”的变量是不能被回收的,因为他们正在被使⽤。当变量离开环境时,就会被标记为“离开环境”,被标记为“离开环境”的变量会被内存释放。

● 垃圾收集器在运⾏的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引⽤的标记。⽽在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经⽆法访问到这些变量了。最后。垃圾收集器完成内存清除⼯作,销毁那些带标记的值,并回收他们所占⽤的内存空间。
(2)引⽤计数
● 另外⼀种垃圾回收机制就是引⽤计数,这个⽤的相对较少。引⽤计数就是跟踪记录每个值被引⽤的次数。当声明了⼀个变量并将⼀个引⽤类型赋值给该变量时,则这个值的引⽤次数就是1。相反,如果包含对这个值引⽤的变量⼜取得了另外⼀个值,则这个值的引⽤次数就减1。当这个引⽤次数变为0时,说明这个变量已经没有价值,因此,在在机回收期下次再运⾏时,这个变量所占有的内存空间就会被释放出来。

● 这种⽅法会引起循环引⽤的问题:例如: obj1 和 obj2 通过属性进⾏相互引⽤,两个对象的引⽤次数都是2。当使⽤循环计数时,由于函数执⾏完后,两个对象都离开作⽤域,函数执⾏结束,obj1 和 obj2 还将会继续存在,因此它们的引⽤次数永远不会是0,就会引起循环引⽤。

function fun() {let obj1 = {}let obj2 = {}obj1.a = obj2 // obj1 引用了 obj2obj2.a = obj1 // obj2 引用了 obj1
}

这种情况下,就要⼿动释放变量占⽤的内存:

obj1.a = null
obj2.a = null

(3) 减少垃圾回收
虽然浏览器可以进⾏垃圾⾃动回收,但是当代码⽐较复杂时,垃圾回收所带来的代价⽐较⼤,所以应该尽量减少垃圾回收。
对数组进⾏优化:在清空⼀个数组时,最简单的⽅法就是给其赋值为[ ],但是与此同时会创建⼀个新的空对象,可以将数组的⻓度设置为0,以此来达到清空数组的⽬的。
对 object 进⾏优化:对象尽量复⽤,对于不再使⽤的对象,就将其设置为null,尽快被回收。
对函数进⾏优化:在循环中的函数表达式,如果可以复⽤,尽量放在函数的外⾯。

2. 哪些情况会导致内存泄漏

以下四种情况会造成内存的泄漏:
● 意外的全局变量:由于使⽤未声明的变量,⽽意外的创建了⼀个全局变量,⽽使这个变量⼀直留在内存中⽆法被回收。
● 被遗忘的计时器或回调函数:设置了 setInterval 定时器,⽽忘记取消它,如果循环函数有对外部变量的引⽤的话,那么这个变量会被⼀直留在内存中,⽽⽆法被回收。
● 脱离 DOM 的引⽤:获取⼀个 DOM 元素的引⽤,⽽后⾯这个元素被删除,由于⼀直保留了对这个元素的引⽤,所以它也⽆法被回收。
● 闭包:不合理的使⽤闭包,从⽽导致某些变量⼀直被留在内存当中。

相关文章:

前端高频面试题 js中堆和栈的区别和浏览器的垃圾回收机制

一、 栈(stack)和 堆(heap) 栈(stack):是栈内存的简称,栈是自动分配相对固定大小的内存空间,并由系统自动释放,栈数据结构遵循FILO(first in last out)先进后出的原则,较为经典的就是乒乓球盒结…...

自然语言处理:大语言模型入门介绍

自然语言处理:大语言模型入门介绍 语言模型的历史演进大语言模型基础知识预训练Pre-traning微调Fine-Tuning指令微调Instruction Tuning对齐微调Alignment Tuning 提示Prompt上下文学习In-context Learning思维链Chain-of-thought提示开发(调用ChatGPT的…...

使用秘籍|如何实现图数据库 NebulaGraph 的高效建模、快速导入、性能优化

本文整理自 NebulaGraph PD 方扬在「NebulaGraph x KubeBlocks」meetup 上的演讲,主要包括以下内容: NebulaGraph 3.x 发展历程NebulaGraph 最佳实践 建模篇导入篇查询篇 NebulaGraph 3.x 的发展历程 NebulaGraph 自 2019 年 5 月开源发布第一个 alp…...

对于pycharm 运行的时候不在cmd中运行,而是在python控制台运行的情况,如何处理?

对于pycharm 运行的时候不在cmd中运行,而是在python控制台运行的情况,如何处理? 比如,你在运行你的代码的时候 它总在python控制台运行,十分难受 解决方法 在pycharm中设置下即可,很简单 选择运行点击…...

Spring MVC 二 :基于xml配置

创建一个基于xml配置的Spring MVC项目。 Idea创建新项目&#xff0c;pom文件引入依赖&#xff1a; <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.12.RELEASE</version>…...

springboot aop方式实现接口入参校验

一、前言 在实际开发项目中&#xff0c;我们常常需要对接口入参进行校验&#xff0c;如果直接在业务代码中进行校验&#xff0c;则会显得代码非常冗余&#xff0c;也不够优雅&#xff0c;那么我们可以使用aop的方式校验&#xff0c;这样则会显得更优雅。 二、如何实现&#xf…...

解决git上传远程仓库时的大文件提交

在git中超过100M的文件会上传失败&#xff0c;而当一个文件超过50M时会给你警告&#xff0c;如下 warning: File XXXXXX is 51.42 MB; this is larger than GitHubs recommended maximum file size of 50.00 MB 解决这种问题&#xff0c;首先在项目的.git文件夹中找到.gitigno…...

HTML学习笔记02

HTML笔记02 页面结构分析 元素名描述header标题头部区域的内容&#xff08;用于页面或页面中的一块区域&#xff09;footer标记脚部区域的内容&#xff08;用于整个页面或页面的一块区域&#xff09;sectionWeb页面中的一块独立区域article独立的文章内容aside相关内容或应用…...

<C++> 内存管理

1.C/C内存分布 让我们先来看看下面这段代码 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char *pChar3 "abcd";int *ptr1 (int *) mal…...

【Java】ByteBuffer类的arrayOffset方法详解+示例

arrayOffset功能详解;arrayOffset在position等于0和非0两种场景下的demo。使用类java.nio.ByteBuffer中的arrayOffset()方法可以获得这个缓冲区的第一个元素在底层支持(backing)数组中的偏移量。 如果这个buffer底层是由数组支持的,那么buffer的postion p对应于数组的index…...

【C++】C++ 引用详解 ⑤ ( 函数 “ 引用类型返回值 “ 当左值被赋值 )

文章目录 一、函数返回值不能是 " 局部变量 " 的引用或指针1、函数返回值常用用法2、分析函数 " 普通返回值 " 做左值的情况3、分析函数 " 引用返回值 " 做左值的情况 函数返回值 能作为 左值 , 是很重要的概念 , 这是实现 " 链式编程 &quo…...

Git,分布式版本控制工具

1.为常用指令配置别名&#xff08;可选&#xff09; 打开用户目录&#xff0c;创建.bashrc文件 &#xff08;touch ~/.bashrc&#xff09; 2.往其输入内容 #用于输出git提交日志 alias git-loggit log --prettyoneline --all --graph --abbrev-commit #用于输出当前目录所有文…...

LeetCode 面试题 02.02. 返回倒数第 k 个节点

文章目录 一、题目二、C# 题解 一、题目 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 注意&#xff1a;本题相对原题稍作改动 点击此处跳转题目。 示例&#xff1a; 输入&#xff1a; 1->2->3->4->5 和 k 2 输出&#xff1a; 4 说…...

SpeedBI数据可视化工具:丰富图表,提高报表易读性

数据可视化工具一大作用就是能把复杂数据可视化、直观化&#xff0c;更容易看懂&#xff0c;也就更容易实现以数据驱动业务管理升级&#xff0c;因此一般的数据可视化工具都会提供大量图形化的数据可视化图表&#xff0c;以提高报表的易懂性&#xff0c;更好地服务企业运营决策…...

编写Dockerfile制作Web应用系统nginx镜像

文章目录 题目要求&#xff1a;一、创建文档&#xff0c;编写Dockerfile文件可以将harbor仓库去启动先起来 二、运行Dockerfile&#xff0c;构建nginx镜像三、推送导私有仓库&#xff0c;也就是我们的harbor仓库 题目要求&#xff1a; 编写Dockerfile制作Web应用系统nginx镜像…...

记录一次微服务连接Nacos异常-errorMsg: Illegal character in authority at index 7:

组件信息 Nacos 2.2.3 SpringCloud微服务 部署环境&#xff1a;centerOS 部署方式&#xff1a;k8s 前言 nacos开启鉴权&#xff0c;nacos地址通过变量方式传入服务中 PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.server-addr", "${NACO…...

【Java】反射 之 调用构造方法

调用构造方法 我们通常使用new操作符创建新的实例&#xff1a; Person p new Person();如果通过反射来创建新的实例&#xff0c;可以调用Class提供的newInstance()方法&#xff1a; Person p Person.class.newInstance();调用Class.newInstance()的局限是&#xff0c;它只…...

Hightopo 使用心得(6)- 3D场景环境配置(天空球,雾化,辉光,景深)

在前一篇文章《Hightopo 使用心得&#xff08;5&#xff09;- 动画的实现》中&#xff0c;我们将一个直升机模型放到了3D场景中。同时&#xff0c;还利用动画实现了让该直升机围绕山体巡逻。在这篇文章中&#xff0c;我们将对上一篇的场景进行一些环境上的丰富与美化。让场景更…...

【Python PEP 笔记】201 - 同步迭代 / zip() 函数的使用方法

原文地址&#xff1a;https://peps.python.org/pep-0201/ PDF 地址&#xff1a; 什么是同步迭代 同步迭代就是用 for 一次循环多个序列。 类似于这样的东西&#xff1a; arr1 [1, 2, 3, 4] arr2 [a, b, c, d] for a, b in arr1, arr2:print(a, b)使用 map 实现 for a, b …...

远程控制:用了向日葵控控A2后,我买了BliKVM v4

远程控制电脑的场景很多&#xff0c;比如把办公室电脑的文件发到家里电脑上&#xff0c;但是办公室电脑旁边没人。比如当生产力用的电脑一般都比较重&#xff0c;不可能随时带在身边&#xff0c;偶尔远程操作一下也是很有必要的。比如你的设备在工况恶劣的环境中&#xff0c;你…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

若依登录用户名和密码加密

/*** 获取公钥&#xff1a;前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...