Contents
  1. 1. Node内存分配
  2. 2. Buffer
  3. 3. 网络编程
  4. 4. 函数
    1. 4.1. Scavenge算法
    2. 4.2. Mark-Sweep&Mark-Compact
    3. 4.3. 不要把内存当缓存
    4. 4.4. 分配小Buffer
    5. 4.5. 分配大Buffer
    6. 4.6. 网络
    7. 4.7. 函数
      1. 4.7.1. 函数重载

Node内存分配

  • Scavenge算法
  • Mark-Sweep&Mark-Compact
  • 不要把内存当缓存(注意设置区间过期时间)

Buffer

  • 分配小Buffer原理
  • 分配大Buffer原理
  • Buffer的拼接(string_decoder)
  • Buffer性能

网络编程

  • TCP
  • UDP
  • http
  • Websocket
  • https实践

函数

  • 匿名函数
  • 递归方法递归
  • 内联函数
  • 将函数视为对象(记忆函数)
  • 函数重载
    • 利用闭包代替if
    • 函数的length

Scavenge算法

新生代的对象主要通过Scavenge算法进行垃圾回收,具体实现采用了Cheney算法。是一种采用复制方式实现垃圾回收的算法。它将堆内存一分为二,每个部分称为semispace。在这两个semispace中,只有一个处于使用中,处于使用中的称为From另一个称为To。当开始进行垃圾回收的时候,会检查from的存活对象,这些存活对象将被复制到T哦中,然后释放非存活对象,然后From和To发生对换。
这个算法典型的是牺牲空间换取时间的,无法大批量运用,但是对于新生代中对象的生命周期短。
晋升有两个条件,是否经历过Scavenge回收,或To空间的内存占用比超过限制。

Mark-Sweep&Mark-Compact

Mark-Sweep是标记清除。分为标记和清除两个阶段,标记阶段遍历堆中所有对象,并标记存活的对象,清除只清除没有被没有被标记的对象。
不过这种方法会在每次清除,会造成内存不连续的情况,因为出现一个大对象的时候,可能会触发垃圾回收,而这次回收是不必要的。
Mrak-Compact是标记整理的意思,标记死亡后会整理把活着的对象像一边移动。

不要把内存当缓存

平时我的编程经常把内存当缓存用,在后端编程需要设置过期策略或者限制大小。P128《Nodejs深入浅出》。

分配小Buffer

Node以8kb为界限来区分大对象还是小对象。
注意如果第一次构造了new Buffer(1),然后构造了new Buffer(8192),会造成空间浪费。

分配大Buffer

超过8kb的Buffer对性爱那个,将会直接分配一个SlowBuffer对象。然后这里的内存是C++定义的。

1
2
3
4
5
6
7
8
9
var fs=require('fs');
var rs=fs.createReadStream('test.md');
var data='';
rs.on('data',function(chunk){
data+=chunk;
});
rs.on('end',function(){
console.log(data);
})

上面代码是很多国外网站的实例,但是一旦流中有宽字节,就会出现问题。
data+=chunk
等于这句
data=data.toString()+chunk.toString();
如果限制一下BUffer的长度就会出现问题。
如果限制为11:
var fs=fs.createReadStream(‘test.md’,{highWaterMark:11});
因为一个汉字占三个字符,剩下的没毒取出来。
怎么解决?
加一句代码:
rs.setEncoding(‘utf-8’)

网络

TCP、UDP这有一个粗略的了解,后期专门看书解决。

函数

匿名函数没有名字的函数。
但是要注意形如这样的

1
var a=function(){};

右边的函数就是一个匿名函数,然后把他的引用附到左边的这个变量上。a是没有name的属性。

递归:
涉及到名字递归,方法递归,还有内联函数的递归。
什么是内联函数呢?
还是上面的例子,稍微做点改变。

1
var a=function test(){};

右边就是一个内联函数,只能这个作用域能访问到,别的访问不到。

把函数当做对象,运用缓存记忆的功能,注意使用注意性能。

1
2
3
4
5
6
function getElements(name)
{
if(!getElements.cache)getElements.cache={};
return getElements.cache[name]=getElements.cache[name]||
document.getElementsByTagName(name);
}

函数重载

对arguments的判断,切片slice然后运用apply什么的。
函数的length就是函数定义的参数个数。
另外一种比较忍者的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function addMethod(object,name,fn){
var old=object[name];
object[name]=function(){
if(fn.length==arguments.length){
return fn.apply(this,arguments)
}else if(typeOf old=='function'){
return old.apply(this,arguments);
}
}
}
var ninja={};
addMethod(ninja,'whatever',function(){})
addMethod(ninja,'whatever',function(a,b){})
addMethod(ninja,'whatever',function(a,b,c){})

Contents
  1. 1. Node内存分配
  2. 2. Buffer
  3. 3. 网络编程
  4. 4. 函数
    1. 4.1. Scavenge算法
    2. 4.2. Mark-Sweep&Mark-Compact
    3. 4.3. 不要把内存当缓存
    4. 4.4. 分配小Buffer
    5. 4.5. 分配大Buffer
    6. 4.6. 网络
    7. 4.7. 函数
      1. 4.7.1. 函数重载