2012-01-23 27 views
28

De acuerdo con la documentación de la clase Node.js Buffer Los buffers se asignan fuera del montón V8.Cuál es el tamaño máximo de un Node.js Buffer

http://nodejs.org/docs/latest/api/buffers.html

datos sin procesar se almacena en instancias de la clase Buffer. Un Buffer es similar a una matriz de enteros, pero corresponde a una asignación de memoria bruta fuera del V8 Heap. Un buffer no puede ser redimensionado.

Necesitaba leer un archivo grande (más de 1GB) y traté de usar fd.readPath() pero recibí un error fatal de V8 porque el archivo era mayor que 1GB.

FATAL ERROR: v8::Object::SetIndexedPropertiesToExternalArrayData() length exceeds max acceptable value 

Esto fue documentado por Google. http://code.google.com/p/v8/issues/detail?id=847

Pensé que usaría un Buffer y estoy ejecutando una versión de 64 bits del nodo 0.6.7 para que mi heap pueda manejar archivos de gran tamaño.

$ file `which node` 
/usr/local/bin/node: Mach-O 64-bit executable x86_64 
$ 

Sin embargo si trato de asignar un búfer de 1 GB me sale el mismo error fatal de V8.

var oneGigInBytes = 1073741824; 
var my1GBuffer = new Buffer(oneGigInBytes); //Crash 

//var mySmallerBuffer = new Buffer(oneGigInBytes-1); //Works 

console.log("done"); 

Si un búfer se asignó fuera del montón V8 que pensé que podría ser capaz de asignar un tamaño de búfer mayor que el límite de 1 GB, pero el código anterior imprime el mismo error exacto como readPath(). Comentando la instancia my1GBuffer y descomentando mySmallerBuffer funciona, parece que 1GB es el límite.

¿Cuál es el tamaño máximo de una instancia de la clase Node.js Buffer? ¿Tiene un límite de 1 GB? Mi solución actual es utilizar una secuencia de lectura y fs.pipe().

var fs = require('fs'); 

process.chdir("/Users/joel/Desktop/testFiles/"); 

var stream = fs.createReadStream('./test1GB_File', { bufferSize: 64 * 1024 }); 
stream.pipe(response); 
+0

Creo que en los casos de archivos grandes está reutilizando la misma instancia de búfer. Por lo tanto, tiene un tamaño fijo que se sigue llenando de datos a medida que lo lee. Eso es lo que es un buffer. –

+0

Ahora tengo curiosidad por saber cuál es la solución. – jcolebrand

+0

¿Necesita 1GB de datos en memoria a la vez? ¿Por qué no está transmitiendo el archivo como si usted fuera lo suficientemente bueno? – fent

Respuesta

23

La longitud máxima es 1 gb - 1byte. constante relevante en el código es v8::internal::ExternalArray::kMaxLength:

https://github.com/v8/v8/blob/c8bf5c35e431d4029e084024501863a4cf907882/src/objects.h#L4647-L4648

+0

en realidad, creo que esta constante se puede reemplazar sin ningún daño con Smi :: kMaxValue y luego en x64 obtendrá al menos 2 GB de búferes. (pero obtener almacenamientos intermedios más grandes requiere cambios significativos en V8). –

+0

Gracias por el enlace a Github. Confirma lo que mostraron mis pruebas. – Joel

+1

Debido a cambios en V8, este ya no es el caso. No estoy 100% seguro de dónde se define actualmente, pero obtengo un tamaño máximo de 2GB-1byte. –

Cuestiones relacionadas