文档章节

js垃圾回收机制和引起内存泄漏的操作

Jack088
 Jack088
发布于 2018/12/18 23:33
字数 2186
阅读 25
收藏 0

JS的垃圾回收机制了解吗?

       Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。

JS中最常见的垃圾回收方式是标记清除。

工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。

工作流程:

1.    垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。

2.    去掉环境中的变量以及被环境中的变量引用的变量的标记。

3.    再被加上标记的会被视为准备删除的变量。

4.    垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。

引用计数 方式

工作原理:跟踪记录每个值被引用的次数。

工作流程:

1.    声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1。

2.    同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.

3.    当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.

4.    当引用次数变成0时,说明没办法访问这个值了。

5.    当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存。

但是循环引用的时候就会释放不掉内存。循环引用就是对象A中包含另一个指向对象B的指针,B中也包含一个指向A的引用。

因为IE中的BOM、DOM的实现使用了COM,而COM对象使用的垃圾收集机制是引用计数策略。所以会存在循环引用的问题。

解决:手工断开js对象和DOM之间的链接。赋值为null。IE9把DOM和BOM转换成真正的JS对象了,所以避免了这个问题。

什么情况会引起内存泄漏?

虽然有垃圾回收机制但是我们编写代码操作不当还是会造成内存泄漏。

1.    意外的全局变量引起的内存泄漏。

原因:全局变量,不会被回收。

解决:使用严格模式避免。

2.    闭包引起的内存泄漏

原因:闭包可以维持函数内局部变量,使其得不到释放。

解决:将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对dom的引用。

3.    没有清理的DOM元素引用

原因:虽然别的地方删除了,但是对象中还存在对dom的引用

解决:手动删除。

4.    被遗忘的定时器或者回调

原因:定时器中有dom的引用,即使dom删除了,但是定时器还在,所以内存中还是有这个dom。

解决:手动删除定时器和dom。

5.    子元素存在引用引起的内存泄漏

原因:div中的ul li  得到这个div,会间接引用某个得到的li,那么此时因为div间接引用li,即使li被清空,也还是在内存中,并且只要li不被删除,他的父元素都不会被删除。

解决:手动删除清空。

 

什么放在内存中?什么不放在内存中?

基本类型是:Undefined/Null/Boolean/Number/String

基本类型的值存在内存中,被保存在栈内存中。从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本。

引用类型:object

引用类型的值是对象,保存在堆内存中。

1.    包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。

2.    js不允许直接访问内存中的位置,也就是不能直接访问操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。

栈和堆的区别
  一、堆栈空间分配区别:
  1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
  2、堆(操作系统): 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
  二、堆栈缓存方式区别:
  1、栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;
  2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
  三、堆栈数据结构区别:
  堆(数据结构):堆可以被看成是一棵树,如:堆排序;
  栈(数据结构):一种先进后出的数据结构。
 

ps:

GC垃圾回收机制:

垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。

不再使用的变量即指那些局部变量,全局变量的生命周期直到浏览器关闭页面才结束,这时会再清除一次。

局部变量只在函数执行过程中存在,这个过程中会给它们分配内存去储存它们的值,然后在函数中使用,直至函数结束,而闭包是因为在函数外还有对这个变量的引用,所以并不会被垃圾回收机制清除。

标记清除法(常用):

垃圾回收器在运行的时候会给储存在内存里的所有变量都加上标记。然后去掉环境中的变量及被环境中的变量引用的变量的标记。在这之后还有标记的变量将被视为要删除的变量。最后,回收机制运行,销毁这些带标记的值并回收他们所占的内存空间。

例:

    function mark(){
        var a = 10; //被标记进入环境
        var b = 20; //被标记进入环境
      }
      mark();       //执行完毕,a,b被标记离开环境

引用计数法:

跟踪记录每个值被引用的次数。声明一个变量且把一个引用数据类型赋给这个变量的时候,这个变量的引用次数+1,如果同个值再被赋给另外一个变量,引用次数再+1。相反,如果包含对这个值的引用的变量又被赋了另外一个值,它的引用次数就-1。引用次数为0时,将被认为是需要回收的值。

问题:循环引用时会造成互相引用的两个变量引用次数都不会为0,将不会被清除,造成内存泄漏。如果需要解决这种问题,则需要手动结束两个变量的互相引用,将变量设置为null。

例:

    function cite(){
        var a = 10; 
        var b = a;  //a被引用,引用次数为1
        var c = a;  //a再次被引用,引用次数为2
        b = {};     //b解除对a的引用,a的引用次数为1
      }

GC机制的缺陷:

GC时会停止响应其他操作。

优化:

分代回收:

与Java的回收策略相似,即将对象分为“临时”与“持久”对象,多回收“临时”对象区,少回收“持久”对象区,这样减少了每次回收时判断遍历的个数,从而减少了每次GC的耗时。

增量回收:

每次处理一点,下次再处理一点,优点是减少了GC的耗时,但中断却较多。
 

本文转载自:https://blog.csdn.net/yingzizizizizizzz/article/details/77333996

共有 人打赏支持
Jack088
粉丝 41
博文 454
码字总数 67220
作品 0
程序员
私信 提问
前端进阶(第一期)-调用堆栈笔记

1-1 理解 Javascript 执行上下文和执行栈 原文地址 知识点有: JavaScript程序的内部执行机制; 理解执行上下文和执行栈; 理解以上知识点有助于理解JavaScript的提升机制、作用域和闭包 执行...

xszi
2018/12/04
0
0
JS高程中的垃圾回收机制与常见内存泄露的解决方法

前言 起因是因为想了解闭包的内存泄露机制,然后想起《js高级程序设计》中有关于垃圾回收机制的解析,之前没有很懂,过一年回头再看就懂了,写篇博客与大家分享一下。如果喜欢的话可以点波赞...

OBKoro1
2018/10/29
0
0
js垃圾回收机制和引起内存泄漏的操作

Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环...

架构师springboot
2018/09/05
0
0
深入JavaScript系列(五):JS与内存

一、内存是什么 我们现在常用的计算机都属于 冯·诺依曼体系计算机, 计算机硬件由 控制器、运算器、存储器、输入设备、输出设备 五大部分组成。 我们通常所说的内存就是 存储器。 常用的内存...

Logan70
2018/12/25
0
0
JavaScript 内存机制(前端同学进阶必备)

简介 每种编程语言都有它的内存管理机制,比如简单的C有低级的内存管理基元,像,。同样我们在学习JavaScript的时候,很有必要了解JavaScript的内存管理机制。 JavaScript的内存管理机制是:内...

梁音
2018/06/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

嵌入式应用选择合适的微控制器

准备所需硬件接口列表 使用微控制器的基本硬件框图,准备一份微控制器需要支持的所有外设接口的列表。微控制器中有两种常见的接口类型需要列出。第一种是通信接口,这些是外围设备,如USB,S...

linuxCool
14分钟前
2
0
Group by使用

概述 GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Excel比较多的话,GROUP BY比较类似Excel里面的透视表。 GROUP BY必须得配合...

小橙子的曼曼
25分钟前
3
0
机械臂写中文

Make Me a Hanzi https://www.skishore.me/makemeahanzi/ 使用uArm Swift Pro机械臂写中文-毛笔字 https://github.com/makelove/Robot_Arm_Write_Chinese...

itfanr
36分钟前
4
0
OSChina 周三乱弹 —— 孤独到都和病毒发生了感情了

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @-冰冰棒- :#今日歌曲推荐# 逃跑计划《一万次悲伤 (Live)》 《一万次悲伤 (Live)》- 逃跑计划 手机党少年们想听歌,请使劲儿戳(这里) 现在...

小小编辑
今天
1K
14
test

//// main.c// Test//// Created by 吕颖 on 2019/1/16.// Copyright © 2019年 carmen. All rights reserved.//#include <stdio.h>#include <stdlib.h>#include <t......

carmen-ly
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部