This is the seventh day of my participation in the First Challenge 2022. For details: First Challenge 2022.

Introduction to the

As an excellent NIO framework, Netty is widely used in various servers and frameworks. The JDK that Netty relies on provided NIO packages in version 1.4. Why would Netty need to write another NIO package if the JDK already has NIO packages?

Not because the JDK isn’t good, but because Netty is a bit demanding.

Extensibility of ByteBuf and ByteBuffer

Before explaining how good ByteBuf in Netty is, let’s look at how ByteBuf in Netty relates to ByteBuffer in the JDK.

Actually, it doesn’t matter. It’s just the name.

ByteBuffer in the JDK, java.nio.byteBuffer, is a basic class in the Java NIO package. It is defined as follows:

public abstract class ByteBuffer
    extends Buffer
    implements Comparable<ByteBuffer>
Copy the code

Netty ByteBuf, io.netty.buffer, is a basic class in netty NIO package. It is defined as follows:

public abstract class ByteBuf 
implements ReferenceCounted, Comparable<ByteBuf>
Copy the code

Both definitions are similar; both are abstract classes and require concrete classes to implement them.

However, if you try to create a class that inherits the JDK’s ByteBuffer, it will not inherit. Why would a class named Abstract not inherit?

A closer look reveals that ByteBuffer defines the following two methods that do not show their scope access:

    abstract byte _get(int i);                          // package-private
    abstract void _put(int i, byte b);                  // package-private
Copy the code

According to the JDK definition, methods that do not display tag scopes are called package by default. When both methods are abstract, only classes in the same package can inherit JDK ByteBuffers.

The realization of the JDK itself, of course, there are five ByteBuffer, they respectively are DirectByteBuffer, DirectByteBufferR, HeapByteBuffer, HeapByteBufferR and MappedByteBuffer.

However, the JDK limits the ability of user-defined classes to extend ByteBuffer. Although this can ensure the safety of the ByteBuffer class in use, it also meets the diversity of user needs.

Since the JDK’s ByteBuffer cannot be extended, it is natural that Netty’s ByteBuf has nothing to do with it.

The ByteBuff in Netty is a reference to the JDK’s ByteBuffer, and has made a number of meaningful improvements to make the ByteBuff more usable.

In contrast to the JDK’s ByteBuffer, ByteBuf in Netty has no limits on how much it can be extended and modified.

Different methods of use

Both byteBuffers in the JDK and Bytebuffs in Netty provide read and write capabilities for various types of data.

Compared to netty’s ByteBuff, ByteBuffer in the JDK is more complex to use because it defines four values that describe the data and usage in ByteBuffer: mark, Position, Limit, and Capacity.

  • Capacity is the number of elements it contains. Capacity is never negative and never changes.
  • Limit is the index of the first element that should not be read or written. Limit is never negative and never larger than its capacity.
  • Position is the index of the next element to read or write. Position is never negative and never greater than its limit.
  • Mark is the index to which the position is reset when the reset method is called. Mark does not necessarily have a value, but when it does, it is never negative and never greater than position.

The relationship between the above 4 values is:

0 <= mark <= position <= limit <= capacity
Copy the code

The JDK also provides three methods for handling the above four tags:

  • Clear: Set limit to capacity and position to 0, indicating that data can be written.
  • Flip: Set limit to the current position and position to 0. Indicates that it can be read.
  • Rewind: Limit unchanged, position set to 0, indicating a re-read.

Is it a big head?

There are too many variables, too many methods, and while you may remember them now, over time you will forget how to use the JDK’s ByteBuffer properly.

Unlike the JDK, netty’s ByteBuff has only two indexes: readerIndex and writerIndex.

In addition to index, ByteBuff also provides a richer read and write API for us to use.

Performance differences

For the JAVa.nio.bytebuffer in the JDK, when we allocate space for it, the buffer is filled with zeros. These zeros, though, might be replaced immediately by something really meaningful. But there is no denying that the process of filling consumes CPU and memory.

In addition, java.nio.ByteBuffer in JDK relies on garbage collector for collection, but as we have mentioned before, There are two internal types of ByteBuffer, one is HeapBuffer, which is managed by JVM. There is no problem with garbage collector for collection.

The problem is that there is also directByteBuffers, which are allocated directly to external memory and are not managed by the JVM. In general, DirectBuffers can exist for a long time. If a large number of directBuffers with short life cycles are allocated for a short period of time, these buffers will not be recycled, resulting in OutofMemoryErrors.

It’s also not that fast to recycle DirectBuffer using the API.

ByteBuf in Netty, by contrast, uses its own managed reference count. When ByteBuf’s reference count returns to zero, the underlying memory space is freed or returned to the memory pool.

Let’s look at the use of direct ByteBuff in Netty:

ByteBufAllocator alloc = PooledByteBufAllocator.DEFAULT; ByteBuf buf = alloc.directBuffer(1024); . buf.release(); / / recycling directBufferCopy the code

Of course, netty’s ability to manage the reference count itself has some drawbacks. The pooled buffer may return only after the pooled buffer has been garbage collected, resulting in a memory leak.

Fortunately, Netty provides four methods for detecting reference count memory leaks:

  • DISABLED Indicates that leak detection is DISABLED
  • SIMPLE – The default detection method, takes 1% buff.
  • ADVANCED – also checks for 1% buffs, but this option shows more leaks.
  • PARANOID – Checks all buffs.

Specific detection options are as follows:

java -Dio.netty.leakDetection.level=advanced ...
Copy the code

conclusion

That’s how a good ByteBuff in Netty compares to the JDK. I need you to put it to work.

This article is available at www.flydean.com/45-netty-by…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many tips you didn’t know waiting for you to discover!

Welcome to pay attention to my public number: “procedures those things”, understand technology, more understand you!