首页 > 系统相关 >了解垃圾回收机制与内存泄漏

了解垃圾回收机制与内存泄漏

时间:2024-12-18 14:29:16浏览次数:5  
标签:泄漏 垃圾 对象 回收 引用 内存

目录

一、垃圾回收机制的基本原理

(1)基本原理理解

(2)回收

二、垃圾回收的算法

1.标记清除算法

2.引用计数算法

三、减少垃圾回收

(1)减少对象创建

(2)优化数据结构及内存分配优化

(3)避免内存泄漏

四、避免内存泄漏的建议

(1)导致内存泄漏

(2)避免内存泄漏


前提:前端的垃圾回收机制主要指的是浏览器中的JavaScript引擎所实现的内存管理机制。这种机制自动回收不再使用的内存空间,以避免内存泄漏和内存溢出等问题。以下是JavaScript垃圾回收机制的详细介绍。

一、垃圾回收机制的基本原理

(1)基本原理理解

浏览器的JavaScript引擎具有自动垃圾回收机制,该机制会定期找出那些不再使用的变量和对象,并释放它们所占用的内存。垃圾回收的主要目标是识别和回收那些已经不可达的对象,即无法从根对象出发直接或间接访问到。

以下是一个简单的JavaScript代码示例,用于说明垃圾回收机制的工作原理:

let dog = new Object();
dog.a = new Array(1);

// 这时dog和dog.a都是可达对象,不会被回收。

dog.a = new Object();

// 之前创建的数组对象成为了不可达对象,将被垃圾回收机制回收。

在这个例子中,当dog.a被重新赋值为一个新的对象时,之前与dog.a关联的数组对象就变成了不可达对象。在垃圾回收过程中,这个数组对象将被标记为垃圾并被回收。

(2)回收

  • 定期会处理不在使用的变量、对象,释放占用的内存。
  • 两种变量:全局变量和局部变量。全局变量会持续到页面卸载;局部变量在声明函数中,从函数执行开始,直到函数执行结束,就会被释放。
  • 特殊情况:当局部变量被外部函数使用时,例如闭包,在函数执行结束后,函数外部的变量仍然指向函数内部的局部变量,此时局部变量仍被使用,所以不会回收。

二、垃圾回收的算法

浏览器中的JavaScript引擎通常使用两种垃圾回收算法:标记清除(Mark-and-Sweep)和引用计数(Reference Counting)。现代浏览器主要使用标记清除算法,因为引用计数算法在处理循环引用时会出现问题。

1.标记清除算法

(1)标记阶段:从根对象,如全局对象、活动函数栈等开始,遍历内存中的对象,并给所有可达的对象打上标记。

(2)清除阶段:遍历整个堆内存,将未被标记的对象进行回收,并释放其占用的内存空间。

2.引用计数算法

每个对象都有一个引用计数器,用于记录当前对象被引用的次数。

当对象被引用时,其引用计数器加1;当对象引用被移除或销毁时,计数器减1。

当对象的引用计数器为0时,即没有任何引用指向它时,该对象被判定为不再被使用,可以回收。

注意:引用计数算法无法处理循环引用的问题。

举例:

// 假如对象A和B
let A = {};
let B = {};
 
// A引用B
A.b = B;
 
// B也引用A
B.a = A;

A.b = null; // A不再引用B,但B仍然通过B.a引用A
B.a = null; // B不再引用A,但A已经没有机会知道B已经释放了对它的引用(在纯引用计数算法中)

由于它们相互引用,它们的引用计数器都不会变为0。看似已经断开了所有对AB的外部引用,由于它们之间的循环引用,它们的引用计数器仍然不为0,所以垃圾回收器如果仅依赖引用计数算法将不会回收它们,这就导致了内存泄漏。

三、减少垃圾回收

浏览器能进行垃圾自动回收,但是我们应该尽量减少垃圾回收。

(1)减少对象创建

对象尽量复用,不在使用的对象将其设置为null,尽快被回收。

(2)优化数据结构及内存分配优化

选择合适的数据结构来存储数据,以减少内存占用;

避免使用不必要的嵌套数据结构,简化数据结构层次;

在清空数组时,最简单的是给其赋值为[],但是会创建一个新的空对象。所以使用数组时,尽量通过修改数组长度设为0来清空数组。

(3)避免内存泄漏

及时解除不再需要的事件监听器和回调函数;

清理定时器或第三方库创建的对象,避免它们一直占用内存......

四、避免内存泄漏的建议

(1)导致内存泄漏

意外的全局变量

被遗忘的计时器或回调函数

脱离DOM的引用

闭包

(2)避免内存泄漏

减少全局变量的使用:全局变量会一直存在于内存中,直到页面关闭。

避免循环引用:循环引用会导致内存泄漏,因为垃圾回收器无法回收这些对象。

及时清理事件监听器和定时器:未清理的事件监听器和定时器会一直存在于内存中。

注意闭包的使用:闭包会保留对外部函数的引用,可能导致外部函数的变量无法被垃圾回收。

优化DOM操作:避免频繁的DOM操作,减少DOM节点的创建和销毁。

  若文章对你有帮助,点赞、收藏加关注吧!

标签:泄漏,垃圾,对象,回收,引用,内存
From: https://blog.csdn.net/qq_53911056/article/details/144338571

相关文章

  • 嵌入式动态内存管理实现V2
    一、说明动态内存管理指的是在程序需要内存时申请,在使用完成后释放,保证以比较少的内存实现更多的软件需求。与之相对的是静态内存,典型的静态内存就是全局变量:在程序启动时到整个生命空间内都占用空间。动态内存的特点就是实现内存的“按需使用”,在嵌入式开发环境中,节省ram实现......
  • C语⾔内存函数
    目录1.memcpy使⽤和模拟实现2.memmove 使⽤和模拟实现3.memset 函数的使⽤4.memcmp 函数的使⽤1.memcpy使⽤和模拟实现void*memcpy(void*destination,constvoid*source,size_tnum);•函数memcpy从source的位置开始向后复制num个字节的......
  • 变量a使用了一段内存,变量b也和a使用了相同的内存,如果b把这段内存释放了,a将变为悬空指
    在C++中,如果两个变量(a 和 b)指向同一段内存,并且其中一个变量(如 b)释放了这段内存,那么这段内存就被标记为可供系统重用的空闲内存。此时另一个变量(a)依然保留原有的指针,但它指向的内存已经被释放,成为 悬空指针(danglingpointer)。关键问题内存释放后的行为如果 b 调用了......
  • C++中出了作用域如何释放内存
    在C++中,是否会在作用域结束后自动释放内存,取决于内存的分配方式:1.栈内存分配如果变量是在 栈(stack)上分配的,那么当变量超出其作用域时,内存会自动释放。示例:栈上分配#include<iostream>usingnamespacestd;voidfunc(){inta=42;//栈上分配cout<<a<......
  • Memory Leak Detector:C++内存泄漏常见原因分析_2024-07-23_09-29-09.Tex
    MemoryLeakDetector:C++内存泄漏常见原因分析C++内存管理基础动态内存分配与释放在C++中,动态内存管理是通过new和delete操作符来实现的。new操作符用于在运行时分配内存,而delete操作符用于释放之前分配的内存。理解动态内存分配与释放的机制对于避免内存泄漏至关重要。......
  • 分布式内存计算引擎Spark
    一、Spark概述定义与背景Spark是一个快速、通用的分布式计算引擎,最初是在加州大学伯克利分校的AMPLab开发的。它旨在处理大规模数据处理任务,如数据分析、机器学习和图计算等。与传统的HadoopMapReduce相比,Spark在性能上有显著的提升,尤其是在迭代计算和交互式查询方面。例如......
  • python基于语音识别的智能垃圾分类系统
    大家好我是蓝天,混迹在java圈的辛苦码农。今天要和大家聊的是一款《python基于语音识别的智能垃圾分类系统》毕业设计项目。项目源码以及部署相关请联系蓝天,文末附上联系信息。......
  • 动态内存管理
    一、malloc和 freemalloc函数负责向内存申请空间,free负责释放空间,它俩是一对  <stdlib.h>molloc申请size个字节大小的空间,这块空间是没有被初始化的,返回类型,如果申请成功,将申请的地址返回,如果失败,返回NULLfree用于释放先前malloc、calloc、realloc申请的空间;......
  • c++容器调用clear会释放内存吗
    只有含reserve()/capacity()成员函数的容器才需要用swapidiom来释放空间,而C++里只有vector和string这两个符合条件。在C++11中可以直接使用shrink_to_fit()。list/deque/set/map等容器是没有reserve()和capacity()这两个成员函数的,因此swap是无用功(除非用......
  • 23、Elasticsearch-fielddata内存使用陡增解决方案
    利用searchAfter分页方式代替From-Size查询或Scroll滚动查询,解决From-Size查询存在的深度翻页问题与Scroll滚动查询存在数据量大响应慢的问题。由于searchAfter分页需要保证排序聚合唯一,当使用_id字段进行排序聚合时,可能会导致fielddata内存使用指标陡增,从而导致集群的内存使用率......