JAVA Zero Copy related knowledge "Go"

Source: Internet
Author: User

Transferred from: https://my.oschina.net/cloudcoder/blog/299944

Summary: Java's zero copy is used more in Web applications. Java's libaries supports zero copy in Linux and UNIX, and the key API is the Java.nio.channel.FileChannel Transferto (), Transferfrom () method. We can use these two methods to transfer the bytes directly from the channel to which it was called to another writable byte channel, in which data is not passed through the application in order to improve the efficiency of the transfer.

Introduced

Java's zero copy is most used in Web applications. Java's libaries supports zero copy in Linux and UNIX, and the key API is the Java.nio.channel.FileChannel Transferto (), Transferfrom () method. We can use these two methods to transfer the bytes directly from the channel to which it was called to another writable byte channel, in which data is not passed through the application in order to improve the efficiency of the transfer.

Many Web applications provide users with a large amount of static content, which means that a lot of data is transmitted to the user through the socket intact after it is read from the hard disk. This operation may not seem to consume the CPU, but in fact it is inefficient: Kernal reads the data from disk and transmits it to the user-level application, Then application again the same content back to the socket at the kernal level. In this scenario, application is actually just an inefficient intermediate medium used to pass data from disk file to the socket.

Data is copied every time it passes through the User-kernel boundary, which consumes the CPU and consumes the bandwidth of the RAM. Fortunately, you can use a technique called zero-copy to get rid of these useless copy. The application uses zero copy to request kernel to transfer disk data directly to the socket, rather than through the application. Zero copy greatly improves application performance and reduces context switching between kernel and user mode

Using kernel buffer as an intermediary (instead of directly uploading data to user buffer) looks less efficient (one copy at a time). In fact, however, kernel buffer is used to raise high performance. The kernel buffer plays the role of read-ahead cache during the reading operation. This can significantly improve performance when the data size of the write request is smaller than the size of kernel buffer. The presence of the kernel buffer in a write operation can make the write request fully asynchronous.

The tragedy is that when the requested data size is much larger than kernel buffer size, the method itself becomes a performance bottleneck. Because data needs to be copied many times between Disk,kernel Buffer,user buffer (full buffer per write).

Zero copy improves performance by eliminating these redundant data copy.

Traditional methods of data replication and the context switches involved:

Transfer a file to another program over the network, within the OS, the copy operation undergoes four times the context switch between user mode and kernel mode, and even the data is copied four times, such as:

The steps are as follows:

    1. The read () call causes a context switch from user mode to kernel mode. Sys_read () was called internally to read data from the file. The first copy is done by DMA (direct memory access) and the contents of the file are read from disk and stored in buffer kernel.
    2. The requested data is then copied to user buffer, at which time read () returns successfully. The return of the call triggers the second context switch: from kernel to user. At this point, the data is stored in the user's buffer.
    3. The Send () Socket call brings a third context switch, this time from user mode to kernel mode. At the same time, a third copy occurred: The data was placed in kernel adress space. Of course, this time the kernel buffer and the first step of buffer are different buffer.
    4. The final send () system call returned and also caused the fourth context switch. At the same time, the fourth copy occurs, and the DMA egine copies data from kernel buffer to protocol engine. The fourth time copy is independent and asynchronous.

Data transfer: Zero copy mode and context conversion involved

In Linux 2.4 and later versions of the kernel (such as Linux 6 or CentOS 6 or more), the developer modified the socket buffer descriptor, so that the network card support gather operation, Further reduce copy operation of the data via kernel. This method not only reduces the context switch, but also eliminates the data copy associated with the CPU. The use of the user level has not changed, but the internal principle has changed:

    1. The TransferTo () method allows the file contents to be copied to the kernel buffer, which is done by the DMA engine.
    2. No data was copied to socket buffer. Instead, the socket buffer is appended with some descriptor information, including the location and length of the data. The DMA engine then transmits data directly from kernel buffer to protocol engine, eliminating the only time that a CPU-intensive copy operation is required.

Code Sample:

Show the process of uploading a file from the client to the server via the network

 

Package Zerocopy;import Java.io.ioexception;import Java.net.inetsocketaddress;import java.net.serversocket;import Java.nio.bytebuffer;import Java.nio.channels.serversocketchannel;import Java.nio.channels.socketchannel;public Class Transfertoserver {Serversocketchannel listener = null;protected void MySetup () {inetsocketaddress listenaddr = new I Netsocketaddress (9026); try {listener = Serversocketchannel.open (); ServerSocket ss = Listener.socket (); ss.setreuseaddress (true); Ss.bind (LISTENADDR); SYSTEM.OUT.PRINTLN ("Listening port:" + listenaddr.tostring ());} catch (IOException e) {System.out.println ("Port binding failed:" + listenaddr.tostring () + "Port may already be in use, Reason for error:" + e.getmessage ()); E.pri Ntstacktrace ();}} public static void Main (string[] args) {transfertoserver DNS = new Transfertoserver ();d ns.mysetup ();d ns.readdata ();} private void ReadData () {Bytebuffer DST = bytebuffer.allocate (4096); try {while (true) {Socketchannel conn = Listener.accep T (); SYSTEM.OUT.PRINTLN ("Created connection:" + conn); conn.configureblocking (true); int nRead = 0;while (nread! =-1) {try {nread = Conn.read (DST);} catch (IOException e) {e.printstacktrace (); nread =-1;} Dst.rewind ();}}} catch (IOException e) {e.printstacktrace ();}}}
 Package Zerocopy;import Java.io.fileinputstream;import java.io.ioexception;import java.net.InetSocketAddress ; Import Java.net.socketaddress;import Java.nio.channels.filechannel;import java.nio.channels.socketchannel;public Class Transfertoclient {public static void main (string[] args) throws IOException {transfertoclient sfc = new TRANSFERTOCL Ient (); Sfc.testsendfile ();} public void Testsendfile () throws IOException {String host = "localhost"; int port = 9026; SocketAddress sad = new Inetsocketaddress (host, Port); Socketchannel sc = Socketchannel.open (); Sc.connect (SAD); sc.configureblocking (true); String fname = "Src/main/java/zerocopy/test.data"; FileChannel fc = new FileInputStream (fname). Getchannel (); Long start = System.nanotime (); Long nsent = 0, Curnset = 0;curnse t = Fc.transferto (0, Fc.size (), SC); SYSTEM.OUT.PRINTLN ("Total number of bytes Sent:" + curnset+ "time-consuming (NS):" + (System.nanotime ()-start), try {sc.close (); Fc.close ();} catch (IOException e) {System.out.println (e);}}} 

Other zero copy usage  

Package Zerocopy;import Java.io.fileinputstream;import Java.io.fileoutputstream;import java.io.IOException;import Java.io.randomaccessfile;import Java.nio.channels.filechannel;public class Zerocopydemo {@SuppressWarnings (" Resource ") public static void Transfertodemo (string from, String to) throws IOException {FileChannel Fromchannel = new Rand Omaccessfile (From, "RW"). Getchannel (); FileChannel Tochannel = new Randomaccessfile (To, "RW"). Getchannel (); Long position = 0;long count = fromchannel.size (); fro Mchannel.transferto (position, count, Tochannel); Fromchannel.close (); Tochannel.close ();} @SuppressWarnings ("resource") public static void Transferfromdemo (string from, String to) throws IOException { FileChannel Fromchannel = new FileInputStream (from). Getchannel (); FileChannel Tochannel = new FileOutputStream (to) Getchannel (); Long position = 0;long count = Fromchannel.size (); Tochannel.transferfrom (Fromchannel, position, count); Fromchannel.close (); Tochannel.close ();} public static void Main (string[]args) throws IOException {String from= "src/main/java/zerocopy/1.data"; String to= "Src/main/java/zerocopy/2.data";//transfertodemo (from,to); Transferfromdemo (from,to);}}
Reference

https://www.ibm.com/developerworks/linux/library/j-zerocopy/

http://blog.csdn.net/flyingqr/article/details/6942645

JAVA Zero Copy related knowledge "Go"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.