简体   繁体   English

node.js缓冲区不为空

[英]node.js Buffer not empty

When I create lots of Buffer s they aren't always empty: 当我创建大量Buffer它们并不总是空的:

for (var i = 0; i < 100; i++) {
    console.log((new Buffer(30)).toString('hex'));
}

(Partial) Output: (部分)输出:

782668013a0000003b00000035000000b0c17900391100003c0000003d00
e4216801ffffffff000000000100000000000000000000003e0000003f00
40c27900100000000100000000000000000000000000000018c379000000
000000000000000000000000000000000000000000000000000000000000 --> Empty
000000000000000000000000000000000000000000000000000000000000 --> Empty
0000000000000000108269014000000041000000c86f79000cf679000000
6611000080c27900c0c27900040000000100000000000000d0c279000000
00000000000000005c2468014200000043000000cc6f7900002668014400

(Partial) Output (without .toString('hex') and only new Buffer(10) ): (部分)输出(没有.toString('hex')和只有new Buffer(10) ):

<Buffer 01 00 00 00 58 db 62 00 b4 86>
<Buffer 90 b9 65 00 08 00 00 00 03 00>
<Buffer 10 ba 65 00 04 00 00 00 00 00>
<Buffer 04 00 00 00 00 00 00 00 00 00>
<Buffer 10 00 00 00 00 00 00 00 70 ba>
<Buffer 00 00 00 00 00 00 00 00 00 00> --> Empty
<Buffer 00 00 00 00 00 00 00 00 00 00> --> Empty
<Buffer ff ff ff ff ff ff ff ff 00 00>
<Buffer 00 00 00 00 0f 00 00 00 8c 6f>
<Buffer 80 ba 65 00 00 00 00 00 aa 00>

I'm running node.js v0.10.33 on a 32-bit Windows 7 machine. 我在32位Windows 7计算机上运行node.js v0.10.33

  • Is this a problem with my specific machine? 这是我的特定机器的问题吗?
  • Is this a general problem (aka. bug) of node.js? 这是node.js的一般问题(又称bug)吗?
  • Is this a problem of a special composition (eg only Windows environments)? 这是一个特殊组合的问题(例如只有Windows环境)?
  • Is this expected and I have to clear the Buffer before I start using it? 这是预期的,我必须在开始使用它之前清除Buffer吗?
  • Is this documented? 这记录了吗?

Update: Better behaviour on v0.11.14 , worse behaviour on v0.8.28 更新: v0.11.14行为更好, v0.11.14行为v0.8.28

tl;dr TL;博士

  • Not a problem with your specific machine, it's on all machines. 您的特定机器没有问题,它在所有机器上。
  • Not a bug. 不是错误。 This behavior exists in all memory allocation libraries. 所有内存分配库中都存在此行为。
  • Not OS depended. 不是操作系统依赖。 All OS behave this way. 所有操作系统都以这种方式运行
  • If you need it initialized, then yes, clear it using Buffer.prototype.fill 如果你需要它初始化,那么是的,使用Buffer.prototype.fill清除它
  • Yes, it's documented in the underlying libraries that nodejs/webkit use: see malloc(3) / stdlib 是的,它在nodejs / webkit使用的底层库中有记录:请参阅malloc(3) / stdlib

This is most likely something that's to be expected when working with API that handles memory allocation, such as Buffer. 这很可能是使用处理内存分配的API时所期望的,例如Buffer。

Buffer is actually using the smalloc module, which you could think of as malloc(3) / free(3) from stdlib.h Buffer实际上是使用了smalloc模块,您可以将其视为来自stdlib.h的 malloc(3) / free(3)

The principle behind malloc is that it only allocates/reserves memory for a pointer - in webkit it might look closer to calloc for ExternalArray on objects. malloc背后的原理是它只为指针分配/保留内存 - 在webkit中,它可能看起来更接近于对象上的ExternalArray的calloc

See http://linux.die.net/man/3/malloc http://linux.die.net/man/3/malloc

The malloc() function allocates size bytes and returns a pointer to the allocated memory. malloc()函数分配大小字节并返回指向已分配内存的指针。 The memory is not initialized. 内存未初始化。

Memory allocation/deallocation does not handle memory initialization, because it's more expensive to go through each byte and set it to 0. 内存分配/释放不处理内存初始化,因为遍历每个字节并将其设置为0会更昂贵。

Besides 0 is not always the initial value you need for a byte. 除了0并不总是一个字节所需的初始值。

And since memory allocation can return a block of memory that has been used before by some other process, it's expected to have data in the newly allocated block. 并且由于内存分配可以返回之前由其他进程使用过的内存块,因此预计会在新分配的块中包含数据。

The general rule is: when allocating memory (such as Buffer does), if you need it initialized use buf.fill(0) ; 一般规则是:在分配内存时(比如Buffer),如果需要初始化,请使用buf.fill(0) ; although this is not always needed since in most scenarios when you need Buffer you already have knowledge of the length of the data, implicitly the contents. 虽然这并不总是需要,因为在大多数情况下,当您需要Buffer时,您已经知道了数据的长度,隐含的内容。

For instance, when you create new Buffer(30) you know your data is 30 bytes long, which means you already have an idea of what the data to be written looks like, so in the end you'll most likely end up with writing each byte, before passing the buffer to something else - therefore no need to prepend an additional initialization loop that will set each byte to 0. 例如,当您创建new Buffer(30)您知道您的数据长度为30个字节,这意味着您已经知道要写入的数据是什么样的,所以最后您很可能最终会写入每个字节,在将缓冲区传递给其他字节之前 - 因此无需预先添加将每个字节设置为0的额外初始化循环。

For buffers where you use bytes as flags/states for an object, you could only initialize those. 对于使用字节作为对象的标志/状态的缓冲区,您只能初始化它们。

Eg if your Buffer(10) uses first 2 bytes as flags for some state, and the other 8 bytes for data, only do buffer[0] = buffer[1] = 0 , to set them to initial 0 value, instead of initializing all 10 bytes, and then doing a write on the last 8 anyway. 例如,如果您的Buffer(10)使用前2个字节作为某些状态的标志,而其他8个字节用于数据,则只执行buffer[0] = buffer[1] = 0 ,将它们设置为初始0值,而不是初始化全部10个字节,然后再对最后8个进行写操作。

One last note: If the memory block returned by memory allocation hasn't been used before, then yes, all bytes are set to 0. However, memory handling is something the OS does - using all sorts of optimisations - therefore it's impossible to predict what memory segment you will get and its contents. 最后一点:如果之前没有使用内存分配返回的内存块,那么是的,所有字节都设置为0.但是,内存处理是操作系统所做的 - 使用各种优化 - 因此无法预测你将得到什么内存段及其内容。

In the lastest versions of Node (v5.10.0+) you can use 在最新版本的Node(v5.10.0 +)中,您可以使用

--zero-fill-buffers

https://nodejs.org/api/buffer.html#buffer_the_zero_fill_buffers_command_line_option https://nodejs.org/api/buffer.html#buffer_the_zero_fill_buffers_command_line_option

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM