Introduction
As an excellent NIO framework, netty is widely used in various servers and frameworks. It is also NIO. The JDK that netty relies on has already provided the nio package in version 1.4. Since the JDK already has the nio package, why should netty write another one?
Not because the JDK is not good, but because the requirements of netty are a bit high.
Scalability of ByteBuf and ByteBuffer
Before explaining how ByteBuf in netty is excellent, let's first look at the relationship between ByteBuf in netty and ByteBuffer in jdk.
In fact, it doesn't matter, it's just that the names are a bit similar.
ByteBuffer in jdk, the full name is java.nio.ByteBuffer, belongs to a basic class in the JAVA nio package. It is defined as follows:
public abstract class ByteBuffer
extends Buffer
implements Comparable<ByteBuffer>
The ByteBuf in netty, the full name is io.netty.buffer, belongs to a basic class in the netty nio package. It is defined as follows:
public abstract class ByteBuf
implements ReferenceCounted, Comparable<ByteBuf>
The definitions of both are very similar, both are abstract classes, and both require concrete classes to implement them.
However, when you try to create a class to inherit JDK's ByteBuffer, you will find that it cannot be inherited. Why can't a class named abstract be inherited?
A careful study will find that in ByteBuffer, the following two methods are defined that do not explicitly mark their scope access:
abstract byte _get(int i); // package-private
abstract void _put(int i, byte b); // package-private
According to the definition of JDK, there is no method to mark the scope. The default access is package. When both methods are abstract, only the class of the same package can inherit JDK's ByteBuffer.
Of course, JDK itself has 5 ByteBuffer implementations, they are DirectByteBuffer, DirectByteBufferR, HeapByteBuffer, HeapByteBufferR and MappedByteBuffer.
But the JDK restricts the extension of ByteBuffer by user-defined classes. Although this can ensure the safety of the ByteBuffer class in use, it also allows the diversity of user needs.
Since JDK's ByteBuffer cannot be extended, it is natural that ByteBuf in netty has nothing to do with it.
ByteBuff in netty refers to JDK's ByteBuffer, and has made many meaningful improvements to make ByteBuff more useful.
Compared with JDK's ByteBuffer, ByteBuf in netty has no extension restrictions, and you can freely extend and modify it.
different ways to use
Both ByteBuffer in JDK and ByteBuff in netty provide read and write functions for various types of data.
But compared to ByteBuff in netty, ByteBuffer in JDK is more complicated to use it, because it defines 4 values to describe the data and usage in ByteBuffer, these four values are: 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 greater 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 its position will be reset when the reset method is called. mark doesn't necessarily have a value, but when it does, it can never be negative and never be greater than position.
The relationship of the above 4 values is:
0 <= mark <= position <= limit <= capacity
Then JDK also provides 3 methods to deal with the above 4 tags:
- clear : Set limit to capacity and position to 0, indicating that it can be written.
- flip : Set limit to current position and position to 0. It means that it can be read.
- rewind : The limit remains unchanged, and the position is set to 0, which means re-reading.
Is it a big head?
Too many variables, too many methods, although you may remember now, but after a while you will forget how to use JDK's ByteBuffer correctly.
Different from JDK, ByteBuff in netty has only two indexes, namely readerIndex and writerIndex.
In addition to index, ByteBuff also provides a richer read and write API for our convenience.
difference in performance
For JDK's java.nio.ByteBuffer, when we allocate space for it, the buffer will be filled with 0. Although these 0s may be replaced by real meaningful values right away. But it is undeniable that the filling process consumes CPU and memory.
In addition, JDK's java.nio.ByteBuffer relies on the garbage collector for recycling, but as we said before, ByteBuffer has two internal types, one is HeapBuffer, which is managed by JVM and uses garbage There is no problem with the collector for recycling.
But the problem is that there is another type of ByteBuffer, DirectByteBuffer, which is directly allocated to external memory and is not managed by the JVM. Generally speaking, DirectBuffer may exist for a long time. If a large number of short-lived lives are allocated in a short time The periodic DirectBuffer will cause these Buffers to be too late to be recycled, resulting in OutOfMemoryError.
In addition, the speed of using the API to recycle DirectBuffer is not so fast.
Relatively speaking, ByteBuf in netty uses its own managed reference count. When the reference count of the ByteBuf is zeroed, the underlying memory space will be released, or returned to the memory pool.
Let's take a look at the use of direct ByteBuff in netty:
ByteBufAllocator alloc = PooledByteBufAllocator.DEFAULT;
ByteBuf buf = alloc.directBuffer(1024);
...
buf.release(); // 回收directBuffer
Of course, netty's own management of reference counts also has some disadvantages. After the pooled buffer is garbage collected, the buffer in the pool may not be returned, resulting in memory leaks.
Fortunately, netty provides 4 methods for detecting reference counting memory leaks, namely:
- DISABLED---Disable leak detection
- SIMPLE --The default detection method, which takes 1% of the buff.
- ADVANCED - Also 1% buff for detection, but this option will show more leak information.
- PARANOID - Detects all buffs.
The specific detection options are as follows:
java -Dio.netty.leakDetection.level=advanced ...
Summarize
The above is the comparison between the excellent ByteBuff in netty and the JDK. Don't use it right away.
This article has been included in http://www.flydean.com/45-netty-bytebuf-bytebuffer/
The most popular interpretation, the most profound dry goods, the most concise tutorials, and many tricks you don't know are waiting for you to discover!
Welcome to pay attention to my official account: "Program those things", understand technology, understand you better!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。