ブラシのインタビューの質問12:ゼロコピーは、それがどのようにでしょうか?

image.png





イオファイルのコピーは、Javaコンテンツの一部を無視することはできないです。

私は私は面接の準備、李富春た、今日の質問は:

ZERO-コピーは、それがどのようにあるのですか?

;空間は、オペレーティングシステムのカーネルの状態空間は、状態空間のユーザーに分割されている

オペレーティング・システム権限反対カーネルモード空間と優先的に、

すなわち空間内の一般ユーザのユーザ・モード・スペース。

同様の方法transforToを使用してゼロコピー手段はスペースなしで、カーネルモードへのディスクスペースから直接、ユーザーモードをコピーファイルをファイルコピーをjava.nioで、その後、ディスクに書き込まれ、IOは不要を避け、消費電力を削減しましたコピーとコンテキストの切り替え、それがより効率的です。

次に、インタビュアーは、いくつかの問題が発生延長することができます。

javaファイルコピーモード

java.ioストリームコピー

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();
        }

    }

}


コードを実行することができます。コピー・プロセスは次のとおりです。それはゼロコピー、スペースおよびスイッチユーザーモードカーネルモードのスペース、比較的長いパス、IO消費とより明確にオンラインコンテキストスイッチが消費する必要はありませんが、それは比較的非効率的なコピーです。



image.png





java.nioChannel式コピー

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();
        }

    }

}

明らかに、ユーザーモード領域を経由せず、ゼロコピー、削減消費とIOコンテキストの切り替え、より効率的に次のように図のコピー処理があります。


image.png





ツールは、ファイルのコピー

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();
        }

    }

}


面接官は、通常、好奇心旺盛のようなので、是非します!ソースで掲示されます:
 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;
    }



根本的なSPI、すなわちServiceLoaderロード可能なネイティブ処理コード、ファイルシステムによって異なります。

以下のように分類:



image.png





私たちは、局所最適化法の中共同祝福を使用し、それがユーザーモード空間にユーザーモード空間から直接、実際にコピーされ、最もUnixFsProviderを使用しますが、それはゼロコピーではない、パフォーマンスがあまりにも悪くないです。

IOの効率を改善する方法


1はIO操作の数を減らす、キャッシュを使用して、

ゼロコピー、即ちtransferTo法類似java.nioのコピーを使用して、2、

3、そのようなコーデック、好ましくはストレートバイナリ伝送として変換の不要な送信を低減します。

バッファ



図バッファのクラス階層次のように:

image.png




他の七つのネイティブbool型は、対応するバッファを有することに加えて、

インタビュアーがあれば詳細を尋ね、最初の前記4つの属性、能力、制限、位置、マークは、

ウェアレベリング処理のByteBuffer再度説明しました。


次いでDirectBufferは、この操作は、ヒープメモリの外部に直接に、より効率的です。良い使用が困難である。しかし、ストリーミングメディア業界がない限り、十分に準備小さいので、直接翻訳ソースを要求しません、一般的にお聞きし、技術専門家を尋ねています。

概要


その後、Benpian何ゼロコピーの問題、とは、javaのファイルシステムのコピー、(カウントされませんサードパーティのライブラリの拡張)を達成するための3方法を紹介し、

その後、簡単には三つの方法が効率を改善し、改善する方法ioを説明しますバッファメモリの使用率は、システム・レベルの導入を行います。

長くないったらしい、私はすぐにこの部分では理にかなった次の図を経て、私はあなたの助けを期待することができます。

image.png

元は容易ではない、私たちの相補性と共通の進歩させ、ソースを明記してください、マルチ通信を歓迎

公開された110元の記事 ウォン称賛10 ビュー20000 +

おすすめ

転載: blog.csdn.net/tian583391571/article/details/105113214