声享正努力加载中...
韩红淑
内存生命周期
Release memory
Allocate memory
Use memory
啥是内存 哈哈哈
从硬件层面看,计算机内存是由大量的 flip flops 所组成的(这里大概查了下,即大量的二进制电路所组成的)。每个 flip flop 包含少量晶体管并能够存储一个比特位。单个的 flip flops 可以通过一个唯一标识符寻址,所以就可以读和覆写它们。因此,理论上,我们可以把整个计算机内存看成是由一个巨大的比特位数组所组成的,这样就可以进行读和写。
当编译代码的时候,编译器会检查原始数据类型并提前计算出程序运行所需要的内存大小。在所谓的静态堆栈空间中,所需的内存大小会被分配给程序。这些变量所分配到的内存所在的空间之所以被称为静态内存空间是因为当调用函数的时候,函数所需的内存会被添加到现存内存的顶部。当函数中断,它们被以 LIFO(后进先出) 的顺序移出内存。比如,考虑如下代码:
int n; // 4 字节
int x[4]; // 4 个元素的数组,每个数组元素 4 个字节
double m; // 8 字节
动态内存分配
不幸的是,想要知道编译时一个变量需要多少内存并没有想象中那般容易
js中的内存分配和使用
var n = 374; // 为数字分配内存
var s = 'sessionstack'; // 为字符串分配内存
var o = {
a: 1,
b: null
}; // 为对象及其值分配内存
var a = [1, null, 'str']; // (类似对象)为数组及其数组元素值分配内存
function f(a) {
return a + 3;
} // 分配一个函数(一个可调用对象)
// 函数表达式也分配一个对象
someElement.addEventListener('click', function() {
someElement.style.backgroundColor = 'blue';
}, false);JavaScript 中使用分配的内存主要指的是内存读写。
可以通过为变量或者对象属性赋值,亦或是为函数传参来使用内存。
释放不再使用的内存
大多数的内存管理问题是出现在这一阶段。
痛点在于检测出何时分配的内存是闲置的。它经常会要求开发者来决定程序中的这段内存是否已经不再使用,然后释放它。
引用是内存垃圾回收算法所依赖的主要概念之一。
var o1 = {
o2: {
x: 1
}
};
// 创建两个对象。
// 'o1' 引用对象 'o2' 作为其属性。全部都是不可回收的。
// 'o3' 是第二个引用 'o1' 对象的变量
var o3 = o1;
o1 = 1; // 现在,原先在 'o1' 中的对象只有一个单一的引用,以变量 'o3' 来表示
// 引用对象的 'o2' 属性。
// 该对象有两个引用:一个是作为属性,另一个是 'o4' 变量
var o4 = o3.o2;
// 'o1' 对象现在只有 0 引用,它可以被作为内存垃圾回收。
// 然而,其 'o2' 属性仍然被变量 'o4' 所引用,所以它的内存不能够被释放。
o3 = '374';
o4 = null;
// 'o1' 中的 'o2' 属性现在只有 0 引用了。所以 'o1' 对象可以被回收。标记-清除算法包含三个步骤:
虽然内存垃圾回收器很方便,但是它们也有其一系列的代价。其中之一便是不确定性。意思即内存垃圾回收具有不可预见性。你不能确定内存垃圾收集的确切时机。这意味着在某些情况下,程序会使用比实际需要更多的内存。在其它情况下,在特定的交互敏感的程序中,你也许需要注意那些内存垃圾收集短暂停时间。虽然不确定性意味着不能够确定什么时候可以进行内存垃圾收集,但是大多数 GC 的实现都是在内存分配期间进行内存垃圾回收的一般模式。如果没有进行内存分配,大多数的内存垃圾回收就会保持闲置状态。考虑以下情况:
在该情况下,大多数的内存垃圾回收器不会再运行任何的内存垃圾回收。换句话说,即使可以对该不可获得的引用进行垃圾回收,但是内存收集器不会进行标记。虽然这不是严格意义上的内存泄漏,但是这会导致高于平常的内存使用率。
四种常见的 JavaScript 内存泄漏
1.全局变量
2.定时器及被遗忘的回调函数
3.闭包
4.源自 DOM 引用
内存管理心得
谢谢大家
