有什么做宝宝辅食的网站吗,设计说明翻译,网站左侧悬浮代码,提供企业门户网站建设1 js 内存机制
内存空间#xff1a;栈内存#xff08;stack#xff09;、堆内存#xff08;heap#xff09; 栈内存#xff1a;所有原始数据类型都存储在栈内存中#xff0c;如果删除一个栈原始数据#xff0c;遵循先进后出#xff1b;如下图#xff1a;a 最先进栈栈内存stack、堆内存heap 栈内存所有原始数据类型都存储在栈内存中如果删除一个栈原始数据遵循先进后出如下图a 最先进栈最后出栈。 堆内存引用数据类型会在堆内存中开辟一个空间并且会有一个十六进制的内存地址在栈内存中声明的变量的值就是十六进制的内存地址。 函数也是引用数据类型我们定一个函数的时候会在堆内存中开辟空间会以字符串的形式存储到堆内存中去如下图 function fn() {var i 10var j 10console.log(i j)
}
// 我们直接打印fn会出现一段字符串
console.log(fn)
// 打印结果
/*f fn() {var i10;var j10;console.log(ij)}
*/// 加上括号才执行里面的代码
fn() // 20 2 垃圾回收 概念我们平时创建所有的数据类型都需要内存 所谓的垃圾回收就是找出那些不再继续使用的变量然后释放出其所占用的内存垃圾回收会按照固定的时间间隔周期性的执行这一操作。 javaScript 使用的垃圾回收机制来自动管理内存垃圾回收是把双刃剑垃圾回收是不可见的 优势可以大幅简化程序的内存管理代码降低程序员的负担减少因长时间运转而带来的内存泄漏问题。 不足程序员无法掌控内存javascript 没有暴露任何关于内存的 api无法强迫进行垃圾回收无法干预内存管理。 引用计数reference counting 跟踪记录每个值被引用的次数如果一个值引用次数是 0就表示这个值不再用到了因此可以将这块内存释放 原理每次引用加 1被释放减 1当这个值的引用次数变成 0 时就将其内存空间释放。 let obj { a: 10 } // 引用1
let obj1 { a: 10 } // 引用1
obj {} //引用减1
obj1 null //引用为0 引用计数的 bug循环引用 // ie8较早的浏览器,现在浏览器不会出现这个问题
function Fn() {var objA { a: 10 }var objB { b: 10 }objA.c objBobjB.c objA
} 2.标记清除现代浏览采用标记清除的方式 环境栈局部 V8 回收策略 新生代垃圾回收
from 和 to 组成一个Semispace半空间当我们分配对象时先在 from 对象中进行分配当垃圾回收运行时先检查 from 中的对象当obj2需要回收时将其留在 from 空间而ob1分配到 to 空间然后进行反转将 from 空间和 to 空间进行互换进行垃圾 回收时将 to 空间的内存进行释放简而言之 from 空间存放不被释放的对象to 空间存放被释放的对象当垃圾回收时将 to 空间的对象全部进行回收 概念 标记清除指的是当变量进入环境时这个变量标记为“进入环境”;而当变量离开环境时则将其标记为“离开环境”最后垃圾收集器完成内存清除工作销毁那些带标记的值并回收它们所占用的内存空间所谓的环境就是执行环境 全局执行环境 最外围的执行环境根据宿主环境的不同表示的执行环境的对象也不一样在浏览器中全局执行环境被认为是 window 对象每个函数都有自己的执行环境当执行流进入一个函数时函数的环境就会被推入一个环境栈中。而在函数执行之后栈将其环境弹出把控制权返回给之前的执行环境ECMAScript 程序中的执行流正是由这个方便的机制控制着全局变量和函数都是作为 window 对象的属性和方法创建的某个执行环境中的所有代码执行完毕后该环境被销毁保存在其中的所有变量和函数定义也随之销毁全局执行环境只有当关闭网页的时候才会被销毁 function foo (){var a 10 // 被标记进入执行环境var b ‘hello’ // 被标记进入执行环境}foo() //执行完毕a 和 b 被标记离开执行环境内存被回收 3 V8 内存管理机制 V8 引擎限制内存的原因 V8 最初为浏览器设计不太可能遇到大量内存的使用场景表层原因防止因为垃圾回收所导致的线程暂停执行的时间过长深层原因按照官方的说法以 1.5G 的垃圾回收为例v8 做一次小的垃圾回收需要 50 毫秒以上做一次非增量的垃圾回收需要 1 秒以上这里的时间是指 javascript 线程暂停执行的时间这是不可接受的 v8 直接限制了内存的大小如果说在 node.js 中操作大内存的对象可以通过去修改设置去完成或者是避开这种限制1.7g 是在 v8 引擎方面做的限制我们可以使用 buffer 对象而 buffer 对象的内存分配是在 c层面进行的c的内存不受 v8 的限制v8 采用可一种分代回收的策略将内存分为两个生代新生代和老生代v8 分别对新生代和老生代使用不同的回收算法来提升垃圾回收效率
新生代对象的晋升新生代中用来存放生命较短的对象老生代存放生命较长的对象
在新生代垃圾回收的过程中当一个对象经过多次复制后依然存活它将会被认为是生命周期较长的对象随后会被移动到老生代中采取新的算法进行管理 在 From 空间和 To 空间进行反转的过程中如果 To 空间中的使用量已经超过了 25%那么就将 From 中的对象直接晋升到老生代内存空间中
老生代垃圾回收有 2 种回收方法
1.标记清除Mark Sweep Mark Sweep 是将需要被回收的对象进行标记在垃圾回收运行时直接释放相应的地址空间,红色的区域就是需要被回收的标记合并Mark Compact Mark Compact 将存活的对象移动到一边将需要被回收的对象移动到另一边然后对需要被回收的对象区域进行整体的垃圾回收 老生代内存空间是一个连续的结构