nodejs 笔记

Posted on June 8, 2014

安装

  • ubuntu: TODO

node 笔记

  • 模块第一次加载后,模块对象会存入缓存,再次加载文件不会执行,直接返回缓存的模块对象对象

      % nodejs
      > a = require('m1')
      Im m1
      {}
      > a = require('m1')
      {}
    
  • module 中的this? 反正不等于module

  • 不要直接给exports赋值,因为exports是一个形参,直接赋值形参会改变形参的引用,但是不能改变作用域外的值, 迂回方案是给module.exports直接赋值

  • 本地变量起一个和模块名称一样的名字是一种惯例, 如 var http = require("http");

  • node中的全局变量属于global命名空间(类似浏览器中的window)

  • require

    • main 主模块对象

      检测是否是主模块module == require.main

      主模块对象的id是.

    • resolve(文件路径)获得模块结对路径, 但不会加载该模块

    • cache 加载过的模块的hash, 键名为模块的完整路径

    • 如果想要重新加载一个js/json文件, 比如这个文件会动态变化, 可以手动删掉缓存: delete require.cache[require.resolve('./test.js')]

  • process.argv

    // print process.argv
    process.argv.forEach(function (val, index, array) {
      console.log(index + ': ' + val);
    });
    
    node process-2.js one two=three four
    0: node
    1: /Users/mjr/work/node/process-2.js
    2: one
    3: two=three
    4: four
    
  • process.nextTick

    执行时机: 第一个异步方法的回调之前, 同步方法会阻塞tick的调用


内存控制

  • 64 位内存分配情况, 32位减半

    新生代内存空间               老生代内存空间
    ----------------------------------------------
    From(16M) | To(16M)  |   1400M
    semispace |semispace |
    ----------------------------------------------
    
  • V8堆内存最大保留空间: 4 * semispace + max_old_generation_size, 64位为1464M, 32位减半

  • 启动时调整内存限制(单位M):

    node --max-new-space-size=512 test.js

    node --max-old-space-size=2048 test.js

  • 新生代只复制活的(空间换时间,空间利用率最多50%),老生代只清除死的(内存利用率高,但是有空隙所以要整理)

  • 全局变量和闭包都无法立即回收,需要有限制地使用

  • process.memoryUsage() 单位字节

    {
      rss: 14118912,      // 常驻内存大小
     heapTotal: 7326976, // 申请到的堆大小
      heapUsed: 3944656   // 已使用的堆大小
    }
    

    rss减去堆内存叫做堆外内存, 堆外内存不由V8分配

  • os.totalmem()系统总内存 os.freemem()系统闲置内存


REPL

  • _ 上次表达式的返回值, 只读不写
  • 代码中打开REPL

      var repl = require('repl');
      var con = repl.start().context; # start 打开console, context用于给REPL上下文传值
      con.someVar = '...';
    
  • 命令:

    • .help
    • .break 放弃编写
    • .clear 清除上下文变量
    • .exit 退出
    • .save 文件名 把输入操作命令输出到文件
    • .load 文件名 加载文件

console

  • log info 标准输出
  • error warn 标准错误输出
  • dir(obj) 检视对象
  • time(label) timeEnd(label) 统计2个相同的label之间的执行时间
  • trace(label) 将当前调用栈输出到标准错误输出
  • assert(bool判断, '错误信息') 如果bool判断是false, 则带上错误信息抛出异常

最佳实践

  • 不要把内存当缓存用
  • 对不用了的全局变量, 尽早释放, 优先使用赋值方式: global_var = null // undefined也行

benchmark

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;

// add tests
suite.add('RegExp#test', function() {
  /o/.test('Hello World!');
})
.add('String#indexOf', function() {
  'Hello World!'.indexOf('o') > -1;
})
// add listeners
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
  console.log('Fastest is ' + this.filter('fastest').pluck('name'));
})
// run async
.run({ 'async': true });  //没明白是什么意思

//±number 是方差
RegExp#test x 15,166,924 ops/sec ±1.22% (88 runs sampled)
String#indexOf x 26,822,097 ops/sec ±0.93% (92 runs sampled)
Fastest is String#indexOf