javascript中有GC(垃圾回收机制)。JavaScript是使用垃圾回收机制的语言,执行环境负责在代码执行时管理内存,会自动将垃圾对象(没有被引用的对象)从内存中销毁。

本教程操作环境:windows7系统、javascript1.8.5版、Dell G3电脑。
垃圾回收相关概念
① 什么是垃圾
没有被使用(引用)的对象就是垃圾。
立即学习“Java免费学习笔记(深入)”;
② 什么是垃圾回收
没有被引用的对象被销毁,内存被释放,就是垃圾回收。
C、C++ 等编程语言需要手动垃圾回收。
Java、JavaScript、PHP、Python 等语言自动垃圾回收。
JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作。我们需要做的只是要将不再使用的对象设置为 null 即可。
引用计数法
思路
let arr = [1, 0, 1] // [1, 0, 1]这块内存被arr引用 引用次数为1
arr = [0, 1, 0] // [1, 0, 1]的内存引用次数为0被释放
// [0, 1, 0]的内存被arr引用 引用次数为1
const tmp = arr // [0, 1, 0]的内存被tmp引用 引用次数为2循环引用问题
Netscape Navigator 3.0 采用
function Example(){
let ObjectA = new Object();
let ObjectB = new Object();
ObjectA.p = ObjectB;
ObjectB.p = ObjectA;
}
Example();ObjectA = null; ObjectB = null;
为了解决循环引用造成的内存泄漏问题,Netscape Navigator 4.0 开始采用标记清除法
到了 2008 年,IE、Firefox、Opera、Chrome 和 Safari 都在自己的 JavaScript 实现中采用标记清理(或 其变体),只是在运行垃圾回收的频率上有所差异。
思路
function Example(n){
const a = 1, b = 2, c = 3;
return n * a * b * c;
}
// 标记Example进入执行上下文
const n = 1; // 标记n进入执行上下文
Example(n); // 标记a,b,c进入执行上下文
console.log(n); // 标记a, b, c离开执行上下文,等待垃圾回收const和let声明提升性能
V8引擎的垃圾回收
V8引擎的垃圾回收采用标记清除法与分代回收法
分为新生代和老生代
新生代
新生代垃圾回收采用
Scavenge算法
分配给常用内存和新分配的小量内存
内存大小
分区
运行
Scavenge算法
新生代 -> 老生代

老生代
老生代采用
mark-sweep标记清除和mark-compact标记整理
通常存放较大的内存块和从新生代分配过来的内存块
1类
2类
3类
1类,然后进行深度优先遍历。2类。3类。标记完成之后,将标记为1类的对象进行内存释放

Mark-compact
垃圾回收完成之后,内存空间是不连续的。
这样容易造成无法分配较大的内存空间的问题,从而触发垃圾回收。
所以,会有Mark-compact步骤将未被回收的内存块整理为连续地内存空间。
频繁触发垃圾回收会影响引擎的性能,内存空间不足时也会优先触发Mark-compact

垃圾回收优化
全局变量
// exm1
function Example(){
exm = 'LeBron'
}
// exm2
function Example(){
this.exm = 'LeBron'
}
Example()未清除的定时器
const timer = setInterval(() => {
//...
}, 1000)
// clearInterval(timer)闭包
function debounce(fn, time) {
let timeout = null;
return function () {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, time);
};
}
const fn = debounce(handler, 1000); // fn引用了timeout未清除的DOM元素引用
const element = {
// 此处引用了DOM元素
button:document.getElementById('LeBron'),
select:document.getElementById('select')
}
document.body.removeChild(document.getElementById('LeBron'))这个其实不难,浏览器原带的开发者工具Performance就可以

1、尽量不在for循环中定义函数
// exm
const fn = (idx) => {
return idx * 2;
}
function Example(){
for(let i=0;i<1000;i++){
//const fn = (idx) => {
// return idx * 2;
// }
const res = fn(i);
}
}2、尽量不在for循环中定义对象
function Example() {
const obj = {};
let res = "";
for (let i = 0; i < 1000; i++) {
// const obj = {
// a: i,
// b: i * 2,
// c: i * 3,
// };
obj.a = i;
obj.b = i * 2;
obj.c = i * 3;
res += JSON.stringify(obj);
}
return res
}3、清空数组
arr = [0, 1, 2] arr.length = 0; // 清空了数组,数组类型不变 // arr = [] // 重新申请了一块空数组对象内存
【推荐学习:javascript高级教程】
以上就是javascript有gc吗的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号