当前位置:网站首页>What is zero copy?
What is zero copy?
2022-06-23 22:09:00 【Great inventor】
One 、I/O Concept
1.1 buffer
Buffer is all I/O The basis of ,I/O It's all about moving data in and out of buffers ; Process execution I/O
operation , It's a request to the operating system , Let it either drain the buffer ( Write ), Or fill the buffer ( read ).
Java Process initiation Read The flow chart of request loading data
Process initiation Read After the request , The kernel received Read After the request , It will first check whether the data required by the process already exists in the kernel space , If it already exists , Then directly put the data Copy
Buffer for process .
If there is no kernel, the command will be sent to the disk controller , Request to read data from disk , The disk controller writes data directly to the kernel Read buffer , This step passes
DMA( Direct memory access , It can be understood as a hardware unit , To liberate CPU Complete the document IO) complete .
Next, the kernel will transfer the data Copy Buffer to process ; If the process starts Write request , Also need to put the data in the user buffer Copy To the kernel Socket
In the buffer , And then through DMA The data Copy To network card , Send out .
You might think it's a waste of space , Every time you need to copy the kernel space data into user space , So zero copy is to solve this problem .
Here is a brief mention , There are two ways about zero copy :
- mmap+write
- Sendfile
1.2 [ Virtual memory &
Virtual address space ](https://links.jianshu.com/go?to=https%3A%2F%2Fwww.huaweicloud.com%2Farticles%2Fdb877ccdd6b6a127789fab82b1aa2cd3.html)
CPU Memory is accessed through addressing .32 position CPU The addressing width of is 0~0xFFFFFFFF , The calculated size is 4G, In other words, the maximum supported physical memory is 4G.
But in practice , Encountered such a problem , The program needs to use 4G Memory , The available physical memory is less than 4G, Cause the program to have to reduce the memory consumption .
In order to solve such problems , modern CPU Introduced MMU(Memory Management Unit Memory management unit ).
MMU The core idea of is to use virtual address instead of physical address , namely CPU Use virtual addresses when addressing , from MMU Responsible for mapping virtual addresses to physical addresses .
MMU The introduction of , Solved the limitation of physical memory , For the program , It's like you're using it 4G Memory is the same .
Virtual memory : Virtual memory is a technology that logically expands physical memory .
The basic idea is to use soft 、 Hardware technology takes the two-level memory of memory and external memory as the first level memory . The implementation of virtual memory technology makes use of automatic coverage and switching technology . Simply put, use a part of the hard disk as memory .
( for example Linux Medium Swap District )
Virtual address space : Virtual address space refers to CPU The range of virtual memory that can be addressed ,Linux
The system will provide a virtual address space for each process ( Physical memory is allocated only when it is actually used ), stay 32 position CPU The address range of this machine is 0x00000000 ~
0xFFFFFFFF In this section of address ( about 4G), Among them high 1G The space is kernel space , Called by the operating system , low 3G The space is user space , Used by users .
Division of virtual space
CPU When addressing , Is addressed by virtual address , And then through MMU( Memory management unit ) Convert virtual address to physical address .
CPU Virtual address addressing
Missing pages interruption : Because only a part of the program is added to memory , So the address you are looking for is not in memory (CPU Generate page missing exception ), If you are out of memory , Would pass
Page replacement algorithm To replace pages in memory , Then add the pages in the external memory to the memory , Keep the program running normally .
[ common
Page replacement algorithm ](https://links.jianshu.com/go?to=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F82746153):
- OPT Page replacement algorithm ( The best page replacement algorithm ) : Ideal situation , Impossible to achieve , Generally as a measure of other permutation algorithms .
- FIFO Page replacement algorithm ( First in first out page replacement algorithm ) : Always weed out the first pages in memory , That is, select the page with the longest stay time in memory to be eliminated .
- LRU Page replacement algorithm ( Page replacement algorithm not used recently ) :LRU(Least Currently Used) The algorithm gives each page an access field , Used to record the time of a page since it was last visited T, When a page has to be eliminated , Select one of the existing pages T The most valuable , That is, the most recent unused page to be eliminated .
- LFU Page replacement algorithm ( At least use the page sorting algorithm ) : LFU(Least Frequently Used) The algorithm will let the system maintain a linked list of pages sorted by the time of the last visit , The first node of the linked list is the recently used page , The end node of the linked list is the longest unused page . When accessing memory , Find the corresponding page , And move it to the top of the list . Page missing , Replace the page at the end of the linked list . That is, the more frequently pages are used in memory , The longer it is retained .
image
The benefits of using virtual addresses instead of physical addresses
- More than one virtual address can point to the same physical memory address ( For one more ).
- The virtual address space can be larger than the actual available physical address ( Extend through virtual memory ).
Take advantage of the first feature You can map the kernel space address and the user space virtual address to the same physical address , ** such DMA
You can fill the buffer that is visible to both kernel and user space processes ** .
image
It omits the copy between kernel and user space ,Java Of java.nio.channels.FileChannel#map Also use this feature of the operating system to improve performance .
The relationship between virtual address space and virtual memory
Through virtual memory technology , The memory we use can be much larger than the physical memory , For example, physical memory 256M, But we can assign to each process 4G Virtual address space of size , When CPU
When executing the code in the virtual address space , Unable to find the required page in memory , You need to look in external memory , This part of external storage , We can use it as memory , This is virtual memory
.( Use virtual memory to explain what virtual memory is / Smile to cry )
Virtual address space is not equal to virtual memory . The virtual address space is a space , It doesn't really exist , Only by CPU A virtual range of addresses . And virtual memory is the real hard disk space .
To put it bluntly , Virtual memory is to solve the problem of insufficient memory ; The virtual address space encapsulates the use of virtual memory , Let the process think that it has a large continuous memory space .
In my submission , Modern computers have enough memory ( The benefits mentioned above 2), The concept of virtual memory and virtual address space can be completely abandoned , But virtual memory and virtual address space have another benefit , He can More than one virtual address can point to the same physical memory ( Virtual memory disk ) Address ( The benefits mentioned above 1), So as to achieve Java Zero copy of .
There is no size limit for virtual memory ?
From the perspective of hardware ,Linux The memory space of the system consists of two parts : Physical memory and SWAP( On disk ) . among SWAP It's virtual space , stay Linux
Is called swap space , If you ever pretend Linux Words , One of the steps is to let you allocate swap space (SWAP) Size , therefore In theory , The size of the virtual space depends on the size of the disk
.
What is? SWAP?
swap space It's an area on a disk , It could be a zone , It can also be a file , Or a combination of them . To put it simply , When the physical memory of the system is tight ,Linux It will save the data that is not frequently accessed in memory to swap On ( Change the page ) , In this way, the system has more physical memory for each process , And when the system needs to access swap When storing content on , then swap The data on is loaded into memory , This is what we often say swap out and swap in.
Is there a size limit for the virtual address space ?
Virtual address space It means CPU The range that can be addressed to virtual memory
, Because the system will provide a virtual memory space for each process ( Physical memory is allocated only when virtual memory is actually used ), So in 32 position CPU The address range of this machine is
0x00000000 ~ 0xFFFFFFFF In this section of address ( about 4G), In other words, you can find 4G Address space of .
Of course ,64 There are basically no restrictions on bit machines , however 64 Bit machine memory is usually in 16G above , Basically, there is enough memory ,“ Change the page ” The possibility of operation is also relatively small , therefore SWAP
It's OK to set it very small .
1.2.1 page & Page frame & A page table
MMU :CPU Use virtual address instead of physical address when addressing , And then by MMU(Memory Management Unit, Memory management unit ) Convert to physical address .
paging (Paging) It's using MMU On the basis of , A memory management mechanism is proposed . ** It keeps the virtual address and physical address in a fixed size
4K( This size seems to be modifiable ) Split into pages (page) And page frames (page frame)** , And make sure the page is the same size as the page frame .
A piece of 4K The virtual address range of size is called page ;
A piece of 4K The physical address range of size is called Page frame ;
A page table : The page table is like a function , Enter the page number , The output is a page frame . The operating system maintains a page table for each process
. So the virtual addresses of different processes may be the same . The page table shows the position of the page frame corresponding to each page in the process .
Relationship among the three
Why should there be a paging mechanism ?
Suppose memory is allocated consecutively ( That is, the program is continuous in physical memory )
1. process A Come in , towards os Yes 200 Of memory space , therefore os hold 0~199 Assigned to A
2. process B Come in , towards os Yes 5 Of memory space ,os hold 200~204 Assigned to it
3. process C Come in , towards os Yes 100 Of memory space ,os hold 205~304 Assigned to it
4. This time the process B Run out , hold 200~204 give back os
But after a long time , As long as the size of the processes appearing in the system >5 Words ,200~204 This space will not be allocated ( as long as A and C Do not exit ).
After a longer time , There will be many in the memory 200~204 Such unusable fragments ……
The paging mechanism allows programs to be logically continuous 、 Physically discrete . That is, on a continuous piece of physical memory , Probably 04( This value depends on the size of the page ) Belong to A, and 59 Belong to B,10~14 Belong to C, So as to ensure that any one “ Memory fragments ” Can be allocated .
The life cycle of a page frame
Although each process has 4g Virtual address space for , But apparently In every short period of time it runs , It requires access to a small amount of space , And these spaces are generally address continuous .
If you really allocate all the physical memory to this process , Then most of the physical memory is wasted . So now generally
Using paging technology ( Divide the virtual address space and physical memory into fixed size blocks ), Create a page table , Map the virtual address space page of the process to the page frame of physical memory . Here, the page table stores the mapping relationship
. then As the process runs , Will distribute pages as needed , Those long unused page frames will be recycled by the operating system .
1.2.2 [Page Cache & Swap Cache & Buffer
Locality principle
When the program is executed, it shows the local law , For a period of time , The execution of the whole program is limited to one part of the program . Accordingly , The memory space accessed by the execution is also limited to a certain memory area , say concretely , Locality usually takes two forms : Time locality and space locality .
- Temporal locality : Memory locations that have been referenced once will be referenced multiple times in the future .
- Spatial locality : If a memory location is referenced , So in the future, the location near him will also be quoted .
Page Cache
In memory ( Including physical memory and virtual memory )
Page Cache Page (4K) In units of , Cache file content . cached Page Cache File data in , It can be read by users faster . meanwhile
For band buffer Write operation of , Data is being written to Page Cache You can immediately return to , Instead of waiting for the data to actually persist to disk
, And then improve the overall performance of the upper application .
In fact, there are only two kinds of contents in the memory
Loaded from a file , for example .class file 、FileChannel#map、FileChannel#transforTo etc. (PageCache) The memory used by the code to run ,map.put()( User space memory )
Swap Cache
On disk
There are often some processes in the system that require a lot during initialization memory( Mainly through malloc Get anonymous page),
After initialization , This part memory This process does not often use , There was no release . This creates a waste of memory .Linux Just thought of a way to put these memory Replace the data in to disk , And then put this memory Mark as recyclable
, then Linux Middle page frame recycling mechanism ( Not ready to introduce ) It's going to put these page Recycle and put these page Give it to processes that need it .
Buffer Cache
In memory
The minimum data unit of a disk is sector, Every time I read or write to a disk, I use sector Operate on the disk as a unit .sector The size depends on the specific disk type , Some for 512Byte,
Some for 4K Bytes. Whether the user wants to read 1 individual byte, still 10 individual byte, When you finally access the disk , All must be with sector Read... For units
, If you read the disk naked , That means the efficiency of data reading will be very low . Again , If the user wants to write to a location on the disk ( to update )1 individual byte The data of , He also has to refresh the whole sector, The implication , It is
** Writing this 1 individual byte Before , We need to put the 1byte The disk where it is sector Read all the data , In memory , Modify the corresponding 1 individual byte data , And then the whole modified sector data , Write to disk in one go . In order to reduce this kind of inefficient access , Improve disk access performance as much as possible , The kernel will be on disk sector Build a layer of cache on , He is in sector An integral multiple of a force unit (block), Cache part sector The data is in memory , When there is a data read request , He can read the corresponding data directly from memory . When there is data written , It can directly update the specified part of the data in memory , And then through asynchronous mode , Write the updated data back to the corresponding disk sector in . This layer of cache is block cache Buffer
Cache.**
The logical relationship between the two types of cache
**Page Cache and Buffer Cache It's two manifestations of one thing : For one Page for , Right up , He's some kind of File One of the Page
Cache, And to the next , He is also a Device A group on the Buffer Cache** .
Before the virtual memory mechanism , The operating system uses the block cache family , But after the advent of virtual memory , Operating system management IO It's more granular , So we use the page caching mechanism , Page caching is page based 、 File oriented caching mechanism .
at present Linux Kernel In the code ,Page Cache and Buffer Cache It's actually unified , Whether it's a document Page Cache still Block Of Buffer Cache Finally, they are unified to Page On .
Java And Page Cache
image
It can be seen from the above figure FileChannel#map Method does not use the space of virtual memory (SwapCache), That can't 2G
Put all the files in memory , So does he treat the file itself as a part of the virtual space ?? So I think
The real meaning of virtual memory should be a technology that can use disk as memory , Make the application think it is in memory ( Through virtual address space ), In fact, only when it is used will it be taken .
Two 、[JVM And Linux
Memory relationship of ](https://links.jianshu.com/go?to=https%3A%2F%2Fcloud.tencent.com%2Fdeveloper%2Farticle%2F1420898)
2.1 Linux Process memory model
JVM In a process (Process) The identity of runs in Linux On the system , understand Linux Memory relationship with process , Is to understand JVM And Linux The basis of memory relationship . The following figure shows the hardware 、 System 、 The summary relationship among the three levels of memory in a process .
image
From the perspective of hardware ,Linux The memory space of the system consists of two parts : Physical memory and SWAP( On disk ) .
Physical memory is Linux The main memory area used when active ;
When physical memory is not enough ,Linux Will put part of the temporarily unused memory data on the disk SWAP In the middle , In order to make more memory available ;
And when you need to use the SWAP When the data is , must First switch it back to memory .
from Linux Look at the system , Except for the boot system BIN District , ** The whole memory space is divided into two parts : Kernel memory (Kernel space)、 User memory (User
space).**
The kernel memory is Linux Memory space used by itself , Mainly for program scheduling 、 Memory allocation 、 Connect hardware resources and other program logic .
User memory is the main space provided to each process , Linux Give each process the same virtual memory space ; This makes processes independent of each other , Mutual interference . It gives
Each process must have a virtual address space , And only when actually used , To allocate physical memory .
As shown in the figure below , about 32 Of Linux system , Generally will 0~3G The virtual memory space is allocated as user space , take 3~4G Virtual memory space allocation For kernel space
;64 The partitioning of bit systems is similar .
image
From a process perspective , User memory that the process can access directly ( Virtual memory space ) Is divided into 5 Parts of : Code section 、 Data area 、 Heap area 、 The stack area 、 Unused area .
- The machine code that holds the application in the code area , The code cannot be modified during operation , Read only and fixed size .
- The data area holds the global data in the application , Static data and some constant strings etc , Its size is also fixed .
- The heap is the space dynamically requested by the runtime program , It belongs to direct application when the program is running 、 Memory resources freed .
- The stack area is used to store the incoming parameters of the function 、 Temporary variable , And return address and other data .
- Unused area is the reserve area for allocating new memory space .
2.2 Process and JVM Memory space
JVM The essence is a process , So its memory space ( Also known as the runtime data area , Pay attention to and JMM The difference between ) There are also general characteristics of the process .
however ,JVM It's not a normal process , It has many new features in memory space , There are two main reasons :
- JVM There are many things that belong to operating system management , Transplanted to JVM Inside , The goal is to reduce the number of system calls ;
- Java NIO, The aim is Reduce be used for Reading and writing IO Of The cost of system calls .
JVM Compare the memory model between process and ordinary process
2.2.1 User memory
Forever
Permanent generation is essentially Java Code area and data area of the program .Java Class in program (class), It will be loaded into different data structures of the whole area , Including constant pools 、 Domain 、 Method data 、 Method body 、 Constructors 、 And special methods in the class 、 Instance initialization 、 Interface initialization, etc . This area is for the operating system , It's part of the pile ; And for Java The program to
say , This is the space for the program itself and static resources , bring JVM Be able to explain the execution of Java Program .
The new generation & Old age
The new generation and the old generation are Java The heap space that the program actually uses , Mainly used for memory object storage ; But its There is an essential difference between the management mode and the ordinary process .
When a normal process allocates space to a memory object at run time , such as C++ perform new In operation , Will trigger a system call to allocate memory space , The thread of the operating system allocates the space according to the size of the object and returns
return ; meanwhile , When the program releases the object , such as C++ perform delete In operation , It also triggers a system call , Notify the operating system that the space occupied by the object is recyclable .
JVM The use of memory is different from that of ordinary processes .JVM To the operating system Apply for a whole memory area
( The specific size can be in JVM Parameter adjustment ) As Java The pile of programs ( They are divided into the new generation and the old generation ); When Java Application memory space , Such as execution new operation ,JVM In this space will be allocated to Java Program , also Java The procedure is not responsible for informing JVM When can I free the space of this object , Garbage object memory space recycling by JVM Conduct .
JVM The advantages of memory management are obvious , Include :
- Reduce the number of system calls ,JVM In giving Java The program allocates memory space without operating system intervention , Only in the Java When the heap size changes, you need to request memory from the operating system or notify the recycling , And every time the general program allocates and reclaims memory space, it needs system call to participate in ;
- Reduce memory leaks , Ordinary programs don't have ( perhaps Not in time ) One of the important reasons for memory leaks is to notify the operating system to free memory space , And by the JVM Unified management , It can avoid the memory leak problem caused by programmers .
Unused area
Unused area is the reserve area for allocating new memory space . For ordinary processes , This area can be used for heap and stack space application and release , This area is used for every heap memory allocation
Domain , So size changes frequently ; about JVM Process for , This area is used when resizing the heap and thread stack , The heap size is generally less adjusted , So the size is relatively stable . The operating system will dynamically resize this area , And this area is usually not allocated physical memory , Just allow the process to request heap or stack space in this area .
2.2.2 Kernel memory
Applications don't usually deal directly with kernel memory , Kernel memory is managed and used by the operating system ; But as the Linux Performance concerns and improvements ,
Some new features enable applications to use kernel memory , Or mapping to kernel space .
Java NIO It is in this context that , It makes full use of Linux New features of the system , Promoted Java programmatic IO performance .
image
The figure above shows Java NIO There is... In the kernel used linux Distribution in the system .nio
buffer It mainly includes :nio Using a variety of channel Used in ByteBuffer、Java Program active use
ByteBuffer.allocateDirector Applying for distribution Buffer.
And in the PageCache Inside ,nio Main memory package used
enclosed :FileChannel.map Mode to open the file mapped、FileChannel.transferTo and
FileChannel.transferFrom The required Cache( The picture shows nio file).
adopt JMX Can be monitored NIO Buffer and mapped
Usage situation , As shown in the figure below . however ,FileChannel The implementation of is native through system calls PageCache, The process is for Java It's transparent , We can't monitor the usage of this part of memory .
image
Linux and Java
NIO Make room for programs to use in kernel memory , The main thing is to reduce the number of copies you don't want , In order to reduce IO The cost of operating system calls . for example , Send the data of the disk file to the network card , Use common methods and NIO when , Data flow comparison is shown in the figure below :
image
Copying data between kernel memory and user memory consumes resources and time , And from the picture above we can see , adopt NIO In a way that reduces 2 Data copy between sub kernel memory and user memory
. This is a Java NIO One of the important mechanisms of high performance ( The other is asynchronous non blocking ).
As can be seen from the above , Kernel memory for Java Program performance is also very important , Therefore, when dividing the system memory usage , Be sure to leave some free space for the kernel .
3、 ... and 、 Zero copy
Tradition IO Pass a file through socket Write
File f = new File("helloword/data.txt");RandomAccessFile file = new RandomAccessFile(file, "r");
byte[] buf = new byte[(int)f.length()];
file.read(buf);
Socket socket = ...;
socket.getOutputStream().write(buf);
The internal workflow is like this :
image
The switching between user mode and kernel mode occurs 3 Time ( This operation is relatively heavyweight ), data copy 了 4 Time .
- java Not in itself IO Reading and writing ability , therefore read After method call , From you to java programmatic User mode Switch to Kernel mode , To call the operating system (Kernel) Reading ability , Read data into Kernel buffer . During this time, the user thread blocks , Operating system usage DMA(Direct Memory Access) To achieve file reading , It will not use cpu
DMA It can also be understood as a hardware unit , To liberate cpu Complete the document IO
- from Kernel mode Switch back to the User mode , Take data from Kernel buffer Read in User buffer ( namely byte[] buf), During this time cpu Will participate in copying , Can't use DMA
- call write Method , At this time, the data is transferred from User buffer (byte[] buf) write in socket buffer ,cpu Will participate in copying
- Next, write data to the network card , This ability java I don't have , So we have to start from User mode Switch to Kernel mode , Call the write ability of the operating system , Use DMA take socket buffer Write the data to the network card , Can't use cpu
You can see that there are many intermediate links ,java Of IO It's not actually a physical device level read / write , It's a copy of the cache , The real reading and writing of the bottom layer is completed by the operating system .
1.0 mmap + write The way
Use mmap+write The way to replace the original read+write The way ,mmap It's a way to map files in memory , Mapping a file or other object to the address space of a process ,
Realize the one-to-one correspondence between the file disk address and the virtual address space of a process .
This will eliminate the original kernel Read buffer Copy Data to user buffer , But you still need the kernel Read Buffer will data Copy To kernel Socket buffer .
image
This way, Reduced one copy of data ( Slave kernel space copy Cache to user space ), The switching times between user mode and kernel mode are not reduced ( Three times )
Code implementation :
File f = new File("helloword/data.txt");RandomAccessFile file = new RandomAccessFile(file, "r");
// In fact, the file is not loaded into memory at this time , Instead, the file is treated as part of the virtual memory , It is not loaded into memory until it is used
MappedByteBuffer buf = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f.length());
Socket socket = ...;
socket.getOutputStream().write(buf);
MappedByteBuffer
image
java.nio.channels.FileChannel#map
The method has three arguments ,MapMode,Position and Size, respectively :
- MapMode: Mapping patterns , Options include :READ_ONLY,READ_WRITE,PRIVATE.
- Position: Where to start mapping , The location of the number of bytes .
- Size: from Position How many bytes back to start .
Let's focus on MapMode, The first two represent read-only and read-write , Of course The requested mapping pattern is affected by Filechannel Object access restrictions ( Is if you this
FileChannel Is read-only so model by READ_WRITE You will also report mistakes. ), ** If enabled on a file without read permission READ_ONLY, Will throw out
NonReadableChannelException** .
PRIVATE The pattern represents the mapping of the copy on write , signify ** adopt put() Any changes made to the method will result in a private copy of the data and only
MappedByteBuffer The example can see . This process No changes will be made to the underlying file ** , And once the buffer is garbage collected (garbage
collected), Those changes will be lost .
Take a look map() Method source code :
public MappedByteBuffer map(MapMode mode, long position, long size)
throws IOException
{... Omit ...
int pagePosition = (int)(position % allocationGranularity);
long mapPosition = position - pagePosition;
long mapSize = size + pagePosition;
try {// If no exception was thrown from map0, the address is valid
addr = map0(imode, mapPosition, mapSize);
} catch (OutOfMemoryError x) {// An OutOfMemoryError may indicate that we've exhausted memory
// so force gc and re-attempt map
System.gc();
try {Thread.sleep(100);
} catch (InterruptedException y) {Thread.currentThread().interrupt();
}
try {addr = map0(imode, mapPosition, mapSize);
} catch (OutOfMemoryError y) {// After a second OOME, fail
throw new IOException("Map failed", y);}
}
// On Windows, and potentially other platforms, we need an open
// file descriptor for some mapping operations.
FileDescriptor mfd;
try {mfd = nd.duplicateForMapping(fd);
} catch (IOException ioe) {unmap0(addr, mapSize);
throw ioe;
}
assert (IOStatus.checkAll(addr));
assert (addr % allocationGranularity == 0);
int isize = (int)size;
Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
if ((!writable) || (imode == MAP_RO)) {return Util.newMappedByteBufferR(isize,
addr + pagePosition,
mfd,
um);
} else {return Util.newMappedByteBuffer(isize,
addr + pagePosition,
mfd,
um);
}
}
The general meaning is adopt Native Method to get the address of the memory map , If you fail ( Out of memory ,OutOfMemoryError), Manual GC Map again .
Finally, the memory mapped address is instantiated MappedByteBuffer,MappedByteBuffer Itself is an abstract class , In fact, the real instantiation here is
DirectByteBuffer.
notes 1: This memory ( Refers to off heap memory , No MappedByteBuffer) Not subject to jvm The impact of recycling , So the memory address is fixed , be conducive to IO Reading and writing .
java Medium DirectByteBuf Object only maintains virtual references to this memory (PhantomReference), Memory reclamation is divided into two steps
DirectByteBuf The object is garbage collected , Add virtual references to the reference queue Access the reference queue through a dedicated thread (sun.misc.Cleaner), Free off heap memory based on virtual references
notes 2: because MappedByteBuffer It is realized through virtual memory technology , So your It is the operating system that determines when to refresh to disk . But there is also a benefit Even if your Java The program hangs up after it's written to memory , As long as the operating system works , Data will be written to disk .
java.nio.MappedByteBuffer#force Sure Force the operating system to write the contents of memory to the hard disk , But it's better to use less .
MappedByteBuffer#get The process
public byte get() {return ((unsafe.getByte(ix(nextGetIndex()))));
}
public byte get(int i) {return ((unsafe.getByte(ix(checkIndex(i)))));
}
private long ix(int i) {return address + (i << 0);
}
map0() The function returns an address address, This eliminates the need to call read or write Method to read and write the file , adopt address You can manipulate files . The underlying the unsafe.getByte Method , adopt (address
- Offset ) Get the data of the specified memory .
- First visit address The memory area pointed to , Resulting in missing pages and interruptions , The interrupt response function will find the corresponding page in the exchange area , If you can't find it ( That is, the file has never been read into memory ), The specified page of the file is read from the hard disk to the physical memory ( Not jvm Heap memory ).
- When copying data , Found that physical memory is not enough , Through the virtual memory mechanism (swap) Swap the temporarily unused physical pages into the virtual memory of the hard disk .
summary
- MappedByteBuffer Use virtual memory , So assign (map) The memory size of is not affected by JVM Of -Xmx Parameter limits , But there are also size limits ( From the source code, we can know that the maximum is Integer.MAX_VALUE,2G).
Source code see :sun.nio.ch.FileChannelImpl#map
Essentially due to
java.nio.MappedByteBufferInherit directly fromjava.nio.ByteBuffer, and ByteBuffer The index of is int Type of , therefore MappedByteBuffer It can only be indexed to the maximumInteger.MAX_VALUEThe location of , therefore FileChannel Of map Method will check the validity of parameters .
- once map It's best to limit the size to 1.5G about
- When the file exceeds the limit , Can pass position Parameter reset map What's at the back of the file .
- Use MappedByteBuffer operation A large file Than IO Flow fast ( For small files , Memory mapping file will lead to waste of debris space , Because memory mapping always has to Align page boundaries , The smallest unit is 4 KiB, One 5 KiB The file will be mapped to take 8 KiB Memory , It's a waste 3 KiB Memory .)
- The memory to load the file is Java Out of heap memory , Allow two different processes to access files .
- Don't call... Often MappedByteBuffer.force() Method , This method forces the operating system to write the contents of memory to the hard disk , So if you call after every memory map file you write force() Method , You can't really benefit from memory mapped files , It's the heel disk IO almost .
2.0 Sendfile The way
Sendfile System call in kernel version 2.1 Introduced in , The purpose is to simplify the data transmission process between two channels through the network .
Sendfile Introduction of system call , Not only does it reduce data replication , It also reduces the number of context switches .
image
java There are two channel call transferTo/transferFrom Methods copy data ; Than the way above ** Less 2 Time java
Code ( User mode ) To the operating system ( Kernel mode ) Handoff ** , even ByteBuffer Objects are not created .
image
- java call transferTo After the method , From you to java programmatic User mode Switch to Kernel mode , Use DMA Read data into Kernel buffer , Can't use cpu
- Data from Kernel buffer Transferred to the socket buffer ,cpu Will participate in copying
- Finally using DMA take socket buffer Write the data to the network card , Can't use cpu
Code implementation :
File f = new File("helloword/data.txt");RandomAccessFile file = new RandomAccessFile(file, "r");
Socket socket = ...;
file.getChannel().transferTo(0, f.length(), socket.getChannel());
3.0 Linux 2.4 Further optimization of
We see another time in the kernel space of the previous method copy Using the CPU, So can you take this time copy Also save it ?
Linux2.4 Improvements in the kernel , take Kernel buffer The corresponding data description information in ( Memory address , Offset ) Record the corresponding Socket
In the buffer , One time in kernel space CPU Copy It also saves .
image
- java call transferTo After the method , From you to java programmatic User mode Switch to Kernel mode , Use DMA Read data into Kernel buffer , Can't use cpu
- Only some offset and length Copy information into socket buffer , Almost no consumption
- Use DMA take Kernel buffer Write the data to the network card , Can't use cpu
There is only one switch between user mode and kernel mode in the whole process , The data is copied 2 Time .
summary
So-called 【 Zero copy 】, It's not really no copy , Instead of copying duplicate data to jvm In the memory , The advantages of zero copy are :
- Less switching between user state and kernel state
- Do not use cpu Calculation ( As long as it comes to memory copy You have to use CPU), Reduce cpu Cache pseudo share ( Because zero copy will use DMA data-driven copy, No memory at all , therefore cpu Unable to participate in the calculation )
- Zero copy is suitable for small file transfer ( The file size is too large to fill the kernel buffer ,https://www.cnblogs.com/-wenli/p/13380616.html)
Four 、 Other zero copies
4.1 Netty
Netty Medium
Zero-copyAs we mentioned above OS On the level ofZero-copyNot quite the same. , Netty OfZero-coypIt's completely in user mode (Java level ) Of , itsZero-copyMost of them are inclined toOptimize data operationsThis concept .
Netty A zero copy of Buffer, When transferring data , The final processed data will need to be transmitted to a single message , Combine and split ,NIO Native ByteBuffer
Can't do , Netty By providing Composite( Combine ) and Slice( Split ) Two kinds of Buffer To achieve zero copy ( Reduce... When combining data
copy).
image
TCP layer HTTP The message is divided into two ChannelBuffer, these two items. Buffer To our upper logic (HTTP Handle ) It doesn't make sense .
But the two one. ChannelBuffer To be put together , It becomes a meaningful HTTP message , This message corresponds to
ChannelBuffer, It can be called “Message” Things that are , There's a word here “Virtual Buffer”.
You can look at it Netty Provided CompositeChannelBuffer Source code :
public class CompositeChannelBuffer extends AbstractChannelBuffer {private final ByteOrder order;
private ChannelBuffer[] components;
private int[] indices;
private int lastAccessedComponentId;
private final boolean gathering;
public byte getByte(int index) {int componentId = componentId(index);
return components[componentId].getByte(index - indices[componentId]);
}
... Omit ...
Components It's used to save all the received Buffer,Indices Record each buffer
Starting position ,lastAccessedComponentId Record the last visit ComponentId.
CompositeChannelBuffer It doesn't open up new memory and copy everything directly ChannelBuffer Content , It's about saving everything
ChannelBuffer References to , And in the son ChannelBuffer Read and write in , Zero copy .
4.2 Other zero copies
RocketMQ The messages of are written in sequence to commitlog file , And then use it consume queue Document as index .
RocketMQ Use zero copy mmap+write To respond to Consumer Request .
Again Kafka There is a large number of network data persistent to disk and disk files sent through the network ,Kafka Used Sendfile Zero copy mode .
5、 ... and 、 Test several copy file Of api Speed
Contestant | 3.8M | 394M | 800M |
|---|---|---|---|
FileInputStream | 16s 870ms | ||
BufferedInputStream | 170 ~ 180ms | 15s 989ms | 32s 325ms |
BufferedInputStream with byte1024 | 50 ~ 65ms | 1s 243ms | 3s 418ms |
RandomAccessFile with byte1024 | 50 ~ 65ms | 2s 663ms | 5s 782ms |
FileChannel#write() | 80 ~ 90ms | 3s | 5s 494ms |
FileChannel#transferTo() | 30ms | 593ms | 2s 404ms |
MappedByteBuffer | 30~50ms | 1s 286ms | 4s 968ms |
The first name :FileChannel#transferTo()
proxime accessit :BufferedInputStream with byte1024, little does one think
The third :MappedByteBuffer
A fourth :RandomAccessFile with byte1024
fifth :FileChannel#write(), I didn't expect
边栏推荐
- How to deal with the situation of repeated streaming and chaotic live broadcast in easydss?
- HDLBits-&gt; Circuits-&gt; Arithmetic Circuitd-&gt; 3-bit binary adder
- The latest research progress of domain generalization from CVPR 2022
- How to batch generate video QR code
- 2021-12-19: find the missing numbers in all arrays. Give you an n
- Find my information | Apple may launch the second generation airtag. Try the Lenz technology find my solution
- Intel openvino tool suite advanced course & experiment operation record and learning summary
- Minimize outlook startup + shutdown
- Code implementation of CAD drawing online web measurement tool (measuring distance, area, angle, etc.)
- Basic concepts and common methods of syntactic dependency analysis
猜你喜欢

Outlook開機自啟+關閉時最小化

北大、加州伯克利大學等聯合| Domain-Adaptive Text Classification with Structured Knowledge from Unlabeled Data(基於未標記數據的結構化知識的領域自適應文本分類)

数据可视化之:没有西瓜的夏天不叫夏天

实验五 模块、包和库

《阿里云天池大赛赛题解析》——O2O优惠卷预测

Acl2022 | MVR: multi view document representation for open domain retrieval

How to use the serial port assistant in STC ISP?

《scikit-learn机器学习实战》简介

个税怎么算?你知道吗

Using the provider to transform the shit like code, the amount of code is reduced by 2/3!
随机推荐
Kubernetes cluster lossless upgrade practice
Question: how to understand the network protocol and why the OSI reference model is divided into seven layers
What is the gold content of PMP certificate
[同源策略 - 跨域问题]
Modify jar package
Tencent cloud server ubuntu18 installs MySQL and logs in remotely
[emergency] log4j has released a new version of 2.17.0. Only by thoroughly understanding the cause of the vulnerability can we respond to changes with the same method
How to write test cases efficiently?
Freshman girls' nonsense programming is popular! Those who understand programming are tied with Q after reading
Warpspeed 2021 DFINITY × IAF hacker song demo day ends, and 10 teams win awards
Improve efficiency, take you to batch generate 100 ID photos with QR code
【Proteus仿真】LCD1602+DS1307按键设置简易时钟
Minimize outlook startup + shutdown
The most common usage scenarios for redis
使用 Provider 改造屎一样的代码,代码量降低了2/3!
万字长文!一文搞懂InheritedWidget 局部刷新机制
Notepad++ installing the jsonview plug-in
How to improve the high concurrency of the server
数据可视化之:没有西瓜的夏天不叫夏天
Tencent cloud commercial password compliance solution appears at the 2021 high-end Seminar on commercial password application innovation