Java 0 Copy

Source: Internet
Author: User

1. abstract

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.

2. Introduction

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.

3. The traditional way and the context switch 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.

4. Zero Copy mode and the 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:

The TransferTo () method allows the file contents to be copied to the kernel buffer, which is done by the DMA Engine. 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.

5, 0 Copy Example

To upload a file from the client to the server via the Network:

1 /**2 * Disk-nic 0 copies3  */4 classZerocopyserver {5Serversocketchannel listener =NULL;6 7     protected voidmySetup () {8Inetsocketaddress listenaddr =NewInetsocketaddress (9026);9 Ten         Try { oneListener =Serversocketchannel.open (); aServerSocket SS =Listener.socket (); -Ss.setreuseaddress (true); - Ss.bind (listenaddr); theSystem.out.println ("listening port:" +listenaddr.tostring ()); -}Catch(ioexception E) { -System.out.println ("port binding failed:" + listenaddr.tostring () + "port may already be in use, cause of error:" +e.getmessage ()); - e.printstacktrace (); +         } -  +     } a  at      public Static voidmain (string[] Args) { -Zerocopyserver DNS =NewZerocopyserver (); - Dns.mysetup (); - Dns.readdata (); -     } -  in     Private voidreaddata () { -Bytebuffer DST = bytebuffer.allocate (4096); to         Try { +              while(true) { -Socketchannel conn =listener.accept (); theSystem.out.println ("created connection:" +conn); *Conn.configureblocking (true); $                 intNread = 0;Panax Notoginseng                  while(nread! =-1) { -                     Try { theNread =Conn.read (dst); +}Catch(ioexception E) { a e.printstacktrace (); theNread =-1; +                     } - Dst.rewind (); $                 } $             } -}Catch(ioexception E) { - e.printstacktrace (); the         } -     }Wuyi } the  - classzerocopyclient { wu      public Static voidMain (string[] Args)throwsIOException { -Zerocopyclient sfc =Newzerocopyclient (); about sfc.testsendfile (); $     } -  -      public voidTestsendfile ()throwsIOException { -String host = "localhost"; a         intPort = 9026; +SocketAddress sad =Newinetsocketaddress (host, port); theSocketchannel sc =Socketchannel.open (); - Sc.connect (sad); $Sc.configureblocking (true); the  theString fname = "src/main/java/zerocopy/test.data"; theFileChannel FC =Newfileinputstream (fname). getchannel (); the         LongStart =system.nanotime (); -         LongNsent = 0, Curnset = 0; inCurnset = Fc.transferto (0, fc.size (), sc); theSystem.out.println ("total Number of bytes sent:" + curnset + "time-consuming (ns):" + (system.nanotime ()-start)); the         Try { about sc.close (); the fc.close (); the}Catch(ioexception E) { the System.out.println (e); +         } -     } the}
View Code

0 copies of files to Files:

1 /**2 * Disk-disk 0 copies3  */4 classZerocopyfile {5@SuppressWarnings ("resource")6      public Static voidTransfertodemo (string from, String to)throwsIOException {7FileChannel Fromchannel =NewRandomaccessfile (from, "rw"). Getchannel ();8FileChannel Tochannel =NewRandomaccessfile (to, "rw"). Getchannel ();9 Ten         LongPosition = 0; one         LongCount =fromchannel.size (); a  - Fromchannel.transferto (position, count, tochannel); -  the fromchannel.close (); - tochannel.close (); -     } -  +@SuppressWarnings ("resource") -      public Static voidTransferfromdemo (string from, String to)throwsIOException { +FileChannel Fromchannel =Newfileinputstream (from). getchannel (); aFileChannel Tochannel =Newfileoutputstream (to). getchannel (); at  -         LongPosition = 0; -         LongCount =fromchannel.size (); -  - tochannel.transferfrom (fromchannel, position, count); -  in fromchannel.close (); - tochannel.close (); to     } +  -      public Static voidMain (string[] Args)throwsIOException { theString from = "src/main/java/zerocopy/1.data"; *String to = "src/main/java/zerocopy/2.data"; $         //Transfertodemo (from,to);Panax Notoginseng Transferfromdemo (from, to); -     } the}
View Code6. References

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

Java 0 Copy

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.