1. A Buffer, bir içine bakmak için bir görünümdürArrayBuffer .
BufferAslında A , gerçek belleğin sekizli birim görünümü ("kısmi erişimci") FastBufferolan extends(miras alan) Uint8Arraya'dır , an .ArrayBuffer
📜 Node.js 9.4.0/lib/buffer.js#L65-L73
class FastBuffer extends Uint8Array {
constructor(arg1, arg2, arg3) {
super(arg1, arg2, arg3);
}
}
FastBuffer.prototype.constructor = Buffer;
internalBuffer.FastBuffer = FastBuffer;
Buffer.prototype = FastBuffer.prototype;
2. An'ın boyutu ArrayBufferve görünümünün boyutu değişebilir.
Sebep # 1: Buffer.from(arrayBuffer[, byteOffset[, length]]).
İle Buffer.from(arrayBuffer[, byteOffset[, length]]), Buffertemelini ArrayBufferve görünümün konumunu ve boyutunu belirterek bir oluşturabilirsiniz .
const test_buffer = Buffer.from(new ArrayBuffer(50), 40, 10);
console.info(test_buffer.buffer.byteLength); // 50; the size of the memory.
console.info(test_buffer.length); // 10; the size of the view.
Neden # 2: FastBufferbellek ayırma.
Belleği boyuta bağlı olarak iki farklı şekilde tahsis eder.
- Boyut, bir bellek havuzunun boyutunun yarısından küçükse ve 0 değilse ("küçük") : gerekli belleği hazırlamak için bir bellek havuzunu kullanır.
- Aksi takdirde:
ArrayBuffergerekli belleğe tam olarak uyan bir adanmış oluşturur .
📜 Node.js 9.4.0/lib/buffer.js#L306-L320
function allocate(size) {
if (size <= 0) {
return new FastBuffer();
}
if (size < (Buffer.poolSize >>> 1)) {
if (size > (poolSize - poolOffset))
createPool();
var b = new FastBuffer(allocPool, poolOffset, size);
poolOffset += size;
alignPool();
return b;
} else {
return createUnsafeBuffer(size);
}
}
📜 Node.js 9.4.0/lib/buffer.js#L98-L100
function createUnsafeBuffer(size) {
return new FastBuffer(createUnsafeArrayBuffer(size));
}
" Hafıza havuzu " ile neyi kastediyorsunuz ?
Bir hafıza havuzu sabit boyutlu bir ön tahsis küçük boyutlu bellek parçaları tutmak için bellek bloğu Buffers. Kullanılması, küçük boyutlu bellek yığınlarını sıkıca bir arada tutar, böylece parçalanmayı önler ayrı yönetiminden (ayırma ve ayırma) kaynaklanan .
Bu durumda, bellek havuzları ArrayBuffer, boyutu varsayılan olarak 8 KiB olan ve 'de belirtilen' lerdir Buffer.poolSize. A için küçük boyutlu bir bellek parçası sağlanacağı Bufferzaman, son bellek havuzunun bunu işlemek için yeterli kullanılabilir belleğe sahip olup olmadığını kontrol eder; eğer öyleyse, bu bir oluşturur Bufferolduğunu “görünümler” bellek havuzunun verilen kısmi öbek, aksi takdirde yeni bir bellek havuzu ve benzeri yaratır.
Sen yatan erişebileceği ArrayBuffera Buffer. BufferBireyin buffermülkiyet (miras olduğunu Uint8Array) tutar. Bir “küçük” Buffer 'ın bufferözelliği bir olan ArrayBuffertüm bellek havuzu temsil ettiğini. Yani bu durumda, ArrayBufferve Bufferboyut olarak değişir.
const zero_sized_buffer = Buffer.allocUnsafe(0);
const small_buffer = Buffer.from([0xC0, 0xFF, 0xEE]);
const big_buffer = Buffer.allocUnsafe(Buffer.poolSize >>> 1);
// A `Buffer`'s `length` property holds the size, in octets, of the view.
// An `ArrayBuffer`'s `byteLength` property holds the size, in octets, of its data.
console.info(zero_sized_buffer.length); /// 0; the view's size.
console.info(zero_sized_buffer.buffer.byteLength); /// 0; the memory..'s size.
console.info(Buffer.poolSize); /// 8192; a memory pool's size.
console.info(small_buffer.length); /// 3; the view's size.
console.info(small_buffer.buffer.byteLength); /// 8192; the memory pool's size.
console.info(Buffer.poolSize); /// 8192; a memory pool's size.
console.info(big_buffer.length); /// 4096; the view's size.
console.info(big_buffer.buffer.byteLength); /// 4096; the memory's size.
console.info(Buffer.poolSize); /// 8192; a memory pool's size.
3. Dolayısıyla, " görüntülediği " belleği çıkarmamız gerekir .
An ArrayBufferboyut olarak sabittir, bu yüzden parçanın bir kopyasını oluşturarak onu çıkarmamız gerekir. Bunu yapmak için, kullandığımız Buffer'ın byteOffsetmülkü ve lengthmülk , miras edilir Uint8Arrayve yöntemini bir bir parçası bir kopyasını oluşturur, . İng yöntem, burada esinlenerek @ZachB .ArrayBuffer.prototype.sliceArrayBufferslice()
const test_buffer = Buffer.from(new ArrayBuffer(10));
const zero_sized_buffer = Buffer.allocUnsafe(0);
const small_buffer = Buffer.from([0xC0, 0xFF, 0xEE]);
const big_buffer = Buffer.allocUnsafe(Buffer.poolSize >>> 1);
function extract_arraybuffer(buf)
{
// You may use the `byteLength` property instead of the `length` one.
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.length);
}
// A copy -
const test_arraybuffer = extract_arraybuffer(test_buffer); // of the memory.
const zero_sized_arraybuffer = extract_arraybuffer(zero_sized_buffer); // of the... void.
const small_arraybuffer = extract_arraybuffer(small_buffer); // of the part of the memory.
const big_arraybuffer = extract_arraybuffer(big_buffer); // of the memory.
console.info(test_arraybuffer.byteLength); // 10
console.info(zero_sized_arraybuffer.byteLength); // 0
console.info(small_arraybuffer.byteLength); // 3
console.info(big_arraybuffer.byteLength); // 4096
4. Performans iyileştirme
Sonuçları salt okunur olarak kullanacaksanız veya giriş Bufferiçeriklerini değiştirmeniz uygunsa , gereksiz bellek kopyalamasını önleyebilirsiniz.
const test_buffer = Buffer.from(new ArrayBuffer(10));
const zero_sized_buffer = Buffer.allocUnsafe(0);
const small_buffer = Buffer.from([0xC0, 0xFF, 0xEE]);
const big_buffer = Buffer.allocUnsafe(Buffer.poolSize >>> 1);
function obtain_arraybuffer(buf)
{
if(buf.length === buf.buffer.byteLength)
{
return buf.buffer;
} // else:
// You may use the `byteLength` property instead of the `length` one.
return buf.subarray(0, buf.length);
}
// Its underlying `ArrayBuffer`.
const test_arraybuffer = obtain_arraybuffer(test_buffer);
// Just a zero-sized `ArrayBuffer`.
const zero_sized_arraybuffer = obtain_arraybuffer(zero_sized_buffer);
// A copy of the part of the memory.
const small_arraybuffer = obtain_arraybuffer(small_buffer);
// Its underlying `ArrayBuffer`.
const big_arraybuffer = obtain_arraybuffer(big_buffer);
console.info(test_arraybuffer.byteLength); // 10
console.info(zero_sized_arraybuffer.byteLength); // 0
console.info(small_arraybuffer.byteLength); // 3
console.info(big_arraybuffer.byteLength); // 4096