Java Network Programming - ByteBuf Netty in

Since JDK provided ByteBuffer not dynamic expansion, and the use of complex API and other reasons, Netty provides ByteBuf.
Bytebuf API operations more convenient, expansion may be dynamically provided to achieve a variety of ByteBuf, and efficient mechanism for zero-copy.

ByteBuf operation

ByteBuf has three important properties: capacity capacity, readerIndex reading position, writerIndex writing position
provides readerIndex weiterIndex two variables and pointers to support sequential read and write operations

The following figure shows how a buffer is divided into three regions of two pointers:

img

Code Example:

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import java.util.Arrays;

public class ByteBufDemo {
  public static void main(String[] args) {
    // 1.创建一个非池化的ByteBuf,大小为10个字节
    ByteBuf buf = Unpooled.buffer(10);
    System.out.println("原始ByteBuf为:" + buf.toString());
    System.out.println("1.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");

    // 2.写入一段内容
    byte[] bytes = {1, 2, 3, 4, 5};
    buf.writeBytes(bytes);
    System.out.println("写入的bytes为:" + Arrays.toString(bytes));
    System.out.println("写入一段内容后ByteBuf为:" + buf.toString());
    System.out.println("2.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");

    // 3. 读取一段内容
    byte b1 = buf.readByte();
    byte b2 = buf.readByte();
    System.out.println("读取的bytes为:" + Arrays.toString(new byte[] {b1, b2}));
    System.out.println("读取一段内容后ByteBuf为:" + buf.toString());
    System.out.println("3.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");

    // 4.将读取的内容丢弃
    buf.discardReadBytes();
    System.out.println("将读取的内容丢弃后ByteBuf为:" + buf.toString());
    System.out.println("4.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");

    // 5.清空读写指针
    buf.clear();
    System.out.println("清空读写指针后ByteBuf为:" + buf.toString());
    System.out.println("5.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");

    // 6.再次写入一段内容,比第一段内容少
    byte[] bytes2 = {1, 2, 3};
    buf.writeBytes(bytes2);
    System.out.println("写入的bytes为:" + Arrays.toString(bytes2));
    System.out.println("写入一段内容后ByteBuf为:" + buf.toString());
    System.out.println("6.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");

    // 7.将ByteBuf清零
    buf.setZero(0, buf.capacity());
    System.out.println("清零后ByteBuf为:" + buf.toString());
    System.out.println("7.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");

    // 8.再次写入一段超过容量的内容
    byte[] bytes3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    buf.writeBytes(bytes3);
    System.out.println("写入的bytes为:" + Arrays.toString(bytes));
    System.out.println("写入一段内容后ByteBuf为:" + buf.toString());
    System.out.println("8.ByteBuf中的内容为:" + Arrays.toString(buf.array()) + "\n");
  }
}

ButeBuf dynamic expansion

Default capacity: 256 bytes, the maximum value: Integer.MAX_VALUE (2G)

When writeXXX method calls, checked by the method AbstractByteBuf.ensureWritable0 ()
capacity calculation method: AbstractByteBufAllocator.calculateNewCapacity

The minimum capacity requirements, the corresponding two sets of calculation:
not more than 4 megabytes: 64 bytes and increments twice, until the calculated minimum capacity to meet the new requirements newCapacity
Example: current size 256, 250 has been written , continue to write 10 bytes of data, the required minimum capacity requirement is 261, then the new capacity is 64x2x2x2 = 512

More than 4 megabytes: New new capacity minimum required capacity = / 4 + 4 trillion trillion trillion x4
Example: current size is 3 MB, MB 3 have been written, continue to write 2 MB, the required minimum capacity size of 5 megabytes, then the new capacity is 8 megabytes (can not exceed the maximum value)

4 megabytes of sources: a fixed threshold AbstractByteBufAllocator.CALCULATE_THRESHOLD

The realization ByteBuf

img

Are to apply by ByteBufAllocator distributor in use, along with memory management functions have

PooledByteBuf object reuse memory

PooledThreadCache: PooledByteBufAllocator variable thread instance maintains a
plurality of classification MemoryRegionCache array as a cache memory, MemoryRegionCache internally linked lists, queues which kept Chuck. PoolChuck which maintains memory reference memory approach is to reuse the memory buf points to chuck the memory
PooledByteBufAllocator.ioBuffer combing operation of the process:

img

Zero-copy mechanism

Netty zero-copy mechanism, is to realize an application layer, and underlying the JVM, no excessive memory mechanism associated with the operating system.

  1. CompositeByteBuf, multiple ByteBuf combined into a logical ByteBuf avoided copying between respective ByteBuf

img

  1. wrapedBuffer () method, the byte [] array packaged objects ByteBuf

img

  1. slice () method, the object is cut into a plurality of ByteBuf objects ByteBuf

img

Code Example:

public class ZeroCopyTest {

  public static void main(String[] args) {
    ByteBuf buffer1 = Unpooled.buffer(7);
    buffer1.writeByte(7);
    ByteBuf buffer2 = Unpooled.buffer(7);
    buffer2.writeByte(13);
    CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer();
    CompositeByteBuf newBuf = compositeByteBuf.addComponents(true, buffer1, buffer2);
    System.out.println("CompositeByteBuf:" + newBuf);

    byte[] bytes = {1, 2, 3};
    ByteBuf wrappedBuffer = Unpooled.wrappedBuffer(bytes);
    System.out.println("wrappedBuffer:" + wrappedBuffer.getByte(2));
    bytes[2] = 7;
    System.out.println("wrappedBuffer:" + wrappedBuffer.getByte(2));

    ByteBuf buf = Unpooled.wrappedBuffer("Netty".getBytes());
    ByteBuf slice = buf.slice(1, 2);
    slice.unwrap();
    System.out.println("slice:" + slice);
  }
}

Guess you like

Origin www.cnblogs.com/coding-diary/p/11628391.html