读《代码的未来》
垃圾回收 GC
- GC: Garbage Collection
- 垃圾: 需要回收的对象, 未被引用的对象;
- 根: 判断对象是否被引用的起始点, 基本上是将变量和运行栈空间作为根;
标记清除法:
- 标记阶段(Mark phase): 从根开始递归式的标记出
被引用对象和未引用对象(垃圾); - 清除阶段(Sweep phase): 扫描全部对象, 清除
未引用对象(垃圾), 重置被引用对象的标记, 用于下一次GC;
标记清除法的缺点是, 如果有大量对象并且其中只有小部分存活的情况下, 扫描垃圾对象十分耗时, 复制收集法则克服了这一缺点.
复制收集法:
- 在旧对象所在的空间外, 开辟出一块
新空间; - 将
被引用的对象复制到新空间; - 清空
旧空间;
引用计数法:
- 在每个对象中保存该对象的引用计数, 当引用发生增减时对计数进行更新;
- 清空计数为 0 的垃圾对象;
缺点:
- 引用计数法无法释放循环引用的对象;
- 对引用的增减必须完全正确, 否则会引起很难排查的内存错误;
- 不适合并行处理, 多线程同时对引用计数进行增减的话, 有可能会产生计数不一致的问题;
分代回收法:
- 按照对象生成时间分代, 刚刚生成不久的对象标记为
新生代, 存活很久的对象标记为老生代 - 小回收: 只扫描
新生代对象, 将扫描后依旧存活的对象标记为老生代; - 一次性扫描
老生代;
增量回收法:
- 在程序运行的同时进行 GC 操作, 渐进式的 GC 操作;
- 此方法可以控制 GC 的耗时, 适用于实时性要求高的场景;
并行回收法:
- 充分利用多 CPU 的性能, 在程序运行的同时进行 GC 操作
闭包
什么是闭包?
- 起因: 变量脱离作用域后没有消失, 在某个地方继续存活着;
- 表现: 函数内返回函数, 外部函数可以引用内部函数的局部变量, 此时内部函数叫做闭包函数;
闭包的用途?
- 封装私有变量, "穷人版的面向对象", 闭包和对象是同一事物的正反两面;
- 存储变量;
闭包的缺点?
- 闭包函数中的变量存储在内存中, 无法被回收, 滥用闭包会引起内存泄漏
闭包和对象:
- 闭包和对象都可以实现私有变量
- 二者可以互相模拟
- 没有闭包的编程语言可以用对象来模拟
- 没有对象的编程语言可以用闭包来模拟
闭包和对象是同一事物的正反两面 示例:
// 闭包实现私有变量
function outer() {
var one = 1;
var two = 2;
return function inner(){
return one + two;
};
}
// 对象实现私有变量
var obj = {
one: 1,
two: 2
};
泛型
拥有静态类型的语言, 必然需要带参数的类型 (泛型).
不用泛型的示例:
function identity(arg: number): number {
return arg;
}
或者用 any 类型:
function identity(arg: any): any {
return arg;
}
用泛型, T 用于捕获输入的类型, 返回 T 表示此方法输入和输入类型一致:
function identity<T>(arg: T): T {
return arg;
}

浙公网安备 33010602011771号