Node.js的文档中好像不再推荐new Buffer()方法了,看原因的时候,有这么一句:
The memory allocated for such Buffer instances is not initialized and can contain sensitive data. Such Buffer instances must be initialized manually by using either buf.fill(0) or by writing to the Buffer completely.
意思好像是说为这种方式创建的Buffer对象分配的内存并不是新申请的,而且可能会包含敏感信息?这样的Buffer实例必须手动填满。
这是为什么?
我不是计算机专业出身,有些地方不太理解。我查了下《深入浅出Node.js》的Buffer内存管理部分,确实是用的slab分配策略,小对象的话,是可能使用已经存在的slab单元的。但是使用不是应该是剩下的空白内存部分么?怎么会可能包含信息?而且为什么必须完全地手动来填满?我没学过计算机原理,这块实在不能理解,空着一块内存确实是浪费,但是为什么必须要填满。。。
打个比方。你是店家(node),客人(程序员)来吃饭,你为客户提供碗筷(内存块),但是客人在吃晚饭后不会洗碗(JS没有析构函数一类的东西)。
你为了效率,会重复利用碗筷(slab,内存复用)。
一开始有一部分全新的碗筷给客人用(空白内存),渐渐地,所有碗筷都被用过至少一次了(所有空白内存都被使用过了)
new Buffer()
你把碗筷直接给客户了。如果上个客人没有把碗里的东西清空(析构),那么客人可以轻易地知道上个人吃的是大米饭还是小米饭。所以客人在用碗筷之前必须洗碗。问题在于什么时候洗碗。
你用
new Buffer()
,就表示你只负责重新利用碗筷,客人负责在吃饭前清洗碗筷。而你要是使用Buffer.from
则是你不仅负责重新利用碗筷,还有在给客户之前清洗一下,客人直接使用碗筷。两种方法各有利弊,Unsafe直接分配内存,不用初始化内存,适合我要写1024个字节,我分配1024个字节的buffer;分配到buffer,我直接写入,初始化不初始化其实无所谓。而Buffer.alloc额外初始化一下,如果我要写的数据不知道多少,只是<1024, 那么我就Buffer.alloc(1024)。这样,即时全部读出来,后面的部分也是
\0
不会出现复用了上回存放密码的内存,直接把密码读出来的尴尬情况。