Brush interview questions 12: zero copy is how is it?

image.png





Io file copy is part of the java content can not be ignored.

I was Li Fuchun, I prepare for the interview, today's question is:

ZERO-Copy is how is it?

The space is divided into an operating system kernel state space, the state space user;

kernel mode space opposite the operating system permissions and with higher priority;

user mode space i.e. the space in which the general user.

zero-copy means using a similar method transforTo java.nio the file copy, copy files directly from the disk space to the kernel mode, user mode without space, and then written to disk, io reduced consumption, avoiding unnecessary copy and context switching, it is more efficient.

Next, the interviewer may extend some problems develop:

java file copy mode

java.io stream copy

package org.example.mianshi.filecopy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;

/**
 * 说明:传统的文件copy
 * @author carter
 * 创建时间: 2020年03月26日 9:32 上午
 **/

public class JioFileCopyApp {

    public static void main(String[] args) {

        final File d = new File("/data/appenvs/denv.properties");
        final File s = new File("/data/appenvs/env.properties");

        System.out.println("source file content :" + s.exists());
        System.out.println("target file content :" + d.exists());

        System.out.println("source content:");
        try {
            Files.lines(s.toPath()).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("do file copy !");

        copy(s, d);

        System.out.println("target file content :" + d.exists());
        System.out.println("target content:");
        try {
            Files.lines(d.toPath()).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void copy(File s, File d) {

        try (
                final FileInputStream fileInputStream = new FileInputStream(s);

                final FileOutputStream fileOutputStream = new FileOutputStream(d)
        ) {

            byte[] buffer = new byte[1024];
            int length;
            while ((length = fileInputStream.read(buffer)) > 0) {
                fileOutputStream.write(buffer, 0, length);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}


Code can run; copy process follows: it is not a zero-copy, the space and the need to switch user mode kernel mode space, a relatively long path, IO consumption and on-line context switch consumes more obvious, it is relatively inefficient copy.



image.png





java.nioChannel式copy

package org.example.mianshi.filecopy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;

/**
 * 说明:传统的文件copy
 * @author carter
 * 创建时间: 2020年03月26日 9:32 上午
 **/

public class JnioFileCopyApp {

    public static void main(String[] args) {

        final File d = new File("/data/appenvs/ndenv.properties");
        final File s = new File("/data/appenvs/env.properties");

        System.out.println(s.getAbsolutePath() + "source file content :" + s.exists());
        System.out.println(d.getAbsolutePath() +"target file content :" + d.exists());

        System.out.println("source content:");
        try {
            Files.lines(s.toPath()).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("do file copy !");

        copy(s, d);

        System.out.println(d.getAbsolutePath() +"target file content :" + d.exists());
        System.out.println("target content:");
        try {
            Files.lines(d.toPath()).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void copy(File s, File d) {

        try (
                final FileChannel sourceFileChannel = new FileInputStream(s).getChannel();

                final FileChannel targetFileChannel = new FileOutputStream(d).getChannel()
        ) {

           for (long count= sourceFileChannel.size();count>0;){

               final long transferTo = sourceFileChannel.transferTo(sourceFileChannel.position(), count, targetFileChannel);

               count-=transferTo;

           }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

FIG copy process is as follows: obviously, without going through the user mode space, a zero-copy, reduced consumption and io context switching, more efficient.


image.png





Files tools copy

package org.example.mianshi.filecopy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

/**
 * 说明:Files的文件copy
 * @author carter
 * 创建时间: 2020年03月26日 9:32 上午
 **/

public class FilesFileCopyApp {

    public static void main(String[] args) {

        final File d = new File("/data/appenvs/fenv.properties");
        final File s = new File("/data/appenvs/env.properties");

        System.out.println("source file content :" + s.exists());
        System.out.println("target file content :" + d.exists());

        System.out.println("source content:");
        try {
            Files.lines(s.toPath()).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("do file copy !");

        copy(s, d);

        System.out.println("target file content :" + d.exists());
        System.out.println("target content:");
        try {
            Files.lines(d.toPath()).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void copy(File s, File d) {

        try {
            Files.copy(s.toPath(),d.toPath(), StandardCopyOption.COPY_ATTRIBUTES);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}


Interviewers usually like inquisitive, so come on! Posted at the source:
 public static Path copy(Path source, Path target, CopyOption... options)
        throws IOException
    {
        FileSystemProvider provider = provider(source);
        if (provider(target) == provider) {
            // same provider
            provider.copy(source, target, options);
        } else {
            // different providers
            CopyMoveHelper.copyToForeignTarget(source, target, options);
        }
        return target;
    }



By underlying SPI, i.e. ServiceLoader loadable native handling code different file systems.

Classified as follows:



image.png





We use the most UnixFsProvider, it is actually a copy directly from the user mode space to user mode space, use a joint blessing within the local optimization method, but it is not a zero-copy, performance is not too bad.

How to improve the efficiency of io


1, using the cache, reducing the number of operation io;

2, using zero-copy, i.e. the transferTo method similar java.nio Copy;

. 3, to reduce unnecessary transmission of the conversion, such as codecs, preferably straight binary transmission;

buffer



class hierarchy of FIG buffer as follows:

image.png




In addition to the seven other native bool type has a corresponding Buffer;

interviewer asked if the details, said first four attributes, capacity, limit, position, mark

described again byteBuffer the wear-leveling process.


Then DirectBuffer, this operation is directly outside the heap memory, more efficient. But good use is difficult, unless the streaming media industry, will not ask so small, direct translation source well prepared, are generally asked technical experts to ask you.

summary


Benpian question of what zero-copy, and then introduced the 3 way to achieve the file system copy of the java, (extension of third-party libraries do not count);

then briefly describes three methods io how to improve the efficiency and to improve Buffer memory utilization do system-level introduction.

Not long-winded, I can quickly via the following figure principled In this part, I hope for your help.

image.png

The original is not easy, please indicate the source, let us complementarity and common progress, welcomed the multi-communication

Published 110 original articles · won praise 10 · views 20000 +

Guess you like

Origin blog.csdn.net/tian583391571/article/details/105113214