Junior sister learning java IO: those strange buffers in NiO

brief introduction

Demons and monsters show up quickly. Today, senior brother f helped the younger martial sister to kill demons and demons. What bufferb, bufferl, bufferrb, bufferrl, buffers, bufferu, bufferrs and bufferru are all analyzed for you.

Buffer classification

Younger martial sister: elder martial brother f doesn't say that JDK source code is the best Java teacher? For Cheng does not know the source code, it is in vain to call him a cow. However, when I was studying NiO recently, I found that some buffer classes have no comments, so they are written where abruptly, which makes people very upset.

Is there such a thing? Take elder martial brother f to have a look.

Younger martial sister: elder martial brother F, take shortbuffer as an example. How come its subclasses are followed by some strange characters:

What? Bufferb, bufferl, bufferrb, bufferrl, buffers, bufferu, bufferrs and bufferru are all here. Click in to see their source code, and there is no explanation of what these classes do.

There is such a thing. Give me an hour and let me study it carefully.

An hour later, little sister, after an hour of hard investigation, I found that there was really no official document to introduce the meaning of these categories, but elder martial brother, I pinched my fingers and counted. It seems that I found a little secret between these categories, and I heard it for my brother.

In the previous article, we mentioned that buffers can be divided into shortbuffer, longbuffer, doublebuffer and so on according to their types.

However, according to the nature and usage habits, we can divide it into three categories: bytebufferasxxxbuffer, directxxxbuffer and heapxxxbuffer.

Bytebufferasxxxbuffer mainly converts ByteBuffer into a specific type of buffer, such as charbuffer, intbuffer, etc.

Directxxxbuffer is a buffer that deals with virtual memory mapping.

Finally, heapxxxbuffer is a buffer created on the heap space.

Big endian and little endian

Junior sister, senior brother F, what you just said is not important. I just want to know what B, l, R, s and u do behind the class.

Well, before I explain these contents to you, senior brother, I'll tell you a story.

In the late Ming Dynasty, Wu jiangxue, a talented woman in Zhejiang, wrote a poem: "spring scenery poem"

Younger martial sister, do you see anything special? It's best to read it several times and read it aloud.

Younger martial sister: Wow, senior brother F, this poem reads the same from beginning to end and from end to end. It is symmetrical and artistic conception!

Yes, this is the charm of Chinese. The results are different according to the way of reading. In fact, there are such problems in the computer world.

We know that the lowest storage unit in Java is byte, a byte is 8bits, which is expressed in hexadecimal as ox00 oxff.

In Java, except byte and Boolean occupy one byte, it seems that other types will occupy multiple bytes.

If we take int as an example, int occupies 4 bytes, and its range is from ox00000000 - oxffffff. If we have an int = ox12345678, there are two ways to store it in the memory address.

The first big endian stores the high-order bytes at the starting address

The second little endian stores the bytes of status at the starting address

In fact, big endian is more in line with human reading and writing habits, while little endian is more in line with machine reading and writing habits.

Among the two mainstream CPU camps, PowerPC series uses big endian to store data, while x86 series uses little endian to store data.

If different CPU architectures communicate directly, problems may arise due to different reading sequences.

The original design intention of Java is to write once and run everywhere, so it is natural to do the design.

Therefore, bufferb represents the buffer of big endian, and bufferl represents the buffer of little endian.

Bufferrb and bufferrl represent two read-only buffers.

Aligned memory alignment

Younger martial sister: Senior brother F, what are these for? BufferS,BufferU,BufferRS,BufferRU。

Before we talk about these classes, let's review how objects are stored in the JVM.

Remember how we used JOL to analyze JVM information? The code is very simple:

log.info("{}",VM.current().details());

Output results:

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore,computed addresses are just guesses,and ARE NOT RELIABLE.
# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.
# Objects are 8 bytes aligned.
# Field sizes by type: 4,1,2,4,8,8 [bytes]
# Array element sizes: 4,8 [bytes]

In the above output, we can see that objects are 8 bytes aligned, which means that the allocated bytes of all objects are an integer multiple of 8.

Pay attention to the keyword aligned output above, and confirm that the eyes are the right person.

Aligned means that all objects in the JVM are aligned with 8 bytes. If the space occupied by the object itself is less than 8 bytes or not a multiple of 8 bytes, it will be supplemented.

Still use JOL to analyze string objects:

[main] INFO com.flydean.JolUsage - java.lang.String object internals:
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0    12           (object header)                           N/A
     12     4    byte[] String.value                              N/A
     16     4       int String.hash                               N/A
     20     1      byte String.coder                              N/A
     21     1   boolean String.hashIsZero                         N/A
     22     2           (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 2 bytes external = 2 bytes total

You can see that a string object occupies 24 bytes, but the real meaningful is 22 bytes, and two 2 bytes are used to supplement.

The advantage of alignment is obvious. It is more convenient and fast for the CPU to read data, because the CPU sets how many bytes to read at a time. If your storage is not aligned, the CPU reading efficiency will be relatively low.

Now you can answer some questions: bufferu means unaligned, and bufferru means read-only unaligned.

Younger martial sister: what about buffers and bufferrs?

In fact, this question is still very difficult to answer, but after my senior brother's continuous research and exploration, I finally found the answer:

Let's first look at the differences between directshortbufferru and directshortbufferrs. The differences are in two places. Let's first look at the first order:

DirectShortBufferRU:

public ByteOrder order() {
        return ((ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN)
                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
    }
DirectShortBufferRS:

public ByteOrder order() {
        return ((ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
    }

You can see that the order of directshortbufferru is consistent with the nativeorder. The order of directshortbufferrs is opposite to the nativeorder.

Why the opposite? Let's look at the difference between the two get methods:

DirectShortBufferU:

public short get() {
        try {
            checkSegment();
            return ((UNSAFE.getShort(ix(nextGetIndex()))));
        } finally {
            Reference.reachabilityFence(this);
        }
    }
DirectShortBufferS:

public short get() {
        try {
            checkSegment();
            return (Bits.swap(UNSAFE.getShort(ix(nextGetIndex()))));
        } finally {
            Reference.reachabilityFence(this);
        }
    }

The difference is that directshortbuffers performs a bits swap operation when returning.

Therefore, buffers represents the buffer after swap, and bufferrs represents the read-only buffer after swap.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>