Teknologian jakaminen

Täydellinen lukutaito Java-verkkomallissa

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Yleiskatsaus

Kuvaa NIO:n perustiedot ava-tasolla peruskatsausta varten

1. NIO-katsaus

Javassa NIO (Non-blocking I/O tai New I/O) on Java SE 1.4:ssä ja myöhemmissä versioissa esitelty uusi syöttö/tulostustoimintojen API.

​Perinteiseen IO-malliin verrattuna se tarjoaa paremman tehokkuuden ja paremmat samanaikaiset prosessointiominaisuudet. NIO:n keskeinen ominaisuus on sen estävä ominaisuus, jonka avulla yksi säie voi hallita useita I/O-kanavia, mikä parantaa huomattavasti sovellusten suorituskykyä korkean samanaikaisuuden skenaarioissa.

Java NIO:n käyttöskenaario sopii erityisen hyvin tilanteisiin, joissa on käsiteltävä suuri määrä samanaikaisia ​​yhteyksiä Esimerkiksi verkkopalvelimessa yksi säie voi hallita tuhansia asiakasyhteyksiä ilman, että jokaiselle yhteydelle on varattava erillistä säiettä. Voi vähentää merkittävästi järjestelmän resurssien kulutusta ja parantaa käsittelyominaisuuksia

2. NIO:n kolme pääkomponenttia Javassa

1. Kanavat

Kanava on tietovirran väline Java NIO:ssa. Se on kaksisuuntainen ja sitä voidaan käyttää tietojen lukemiseen tai kirjoittamiseen. Kanavien tärkein etu on, että ne eivät estä, mikä tarkoittaa, että yksi säie voi hallita useita kanavia. Pääkanavatyyppejä ovat:

  • FileChannel: Käytetään tiedostojen luku- ja kirjoitustoimintoihin. Sitä voidaan käyttää tietojen kirjoittamiseen puskurista tiedostoon tai tietojen lukemiseen tiedostosta puskuriin.
  • SocketChannel: Käytetään TCP-yhteyksiin verkkoviestinnässä, ja sitä voidaan käyttää tietojen lukemiseen ja kirjoittamiseen.
  • ServerSocketChannel: Käytetään uusien SocketChannel-yhteyksien hyväksymiseen, kuten perinteinen ServerSocket.
  • DatagramChannel: Käytetään UDP-viestintään, joka voi lähettää ja vastaanottaa datagrammeja.

2. Puskurit

Puskuri on objekti, jota käytetään tietojen tallentamiseen NIO:ssa. Se on tavutaulukko, joka voi kirjoittaa tietoja ja lukea tietoja siitä. Puskurilla on tietty kapasiteetti ja kaksi tärkeää ominaisuutta: sijainti ja raja.

  • Kapasiteetti: elementtien enimmäismäärä, jonka puskuri voi tallentaa.
  • asema: Parhaillaan käytettävän elementin indeksi, joka muuttuu, kun tietoja luetaan tai kirjoitetaan.
  • Raja: Lukutilassa suurin arvo, jonka sijainti voi saavuttaa kirjoitustilassa, sijainti ei voi ylittää arvoa.

Puskurien päätyypit ovatByteBufferCharBufferShortBufferIntBufferLongBufferFloatBufferjaDoubleBuffer, jokainen tyyppi vastaa primitiivistä tietotyyppiä.

3. Valitsimet

Valitsin on NIO:n multiplekseri, jonka avulla yksi säie voi seurata tapahtumia useilta kanavilta, kuten lukea, kirjoittaa, yhdistää ja vastaanottaa tapahtumia. Valitsin ilmoittaa sovellukselle, kun jokin kanavista on valmis I/O-toimintoihin. Valitsimien käyttö parantaa huomattavasti verkkosovellusten samanaikaisuuden käsittelyominaisuuksia, koska jokaiselle yhteydelle ei tarvitse luoda säiettä.

Tärkeimmät valintamenetelmät ovat:

  • select(): Estää, kunnes vähintään yksi kanava on valmis I/O-toimintoja varten.
  • selectedKeys(): Palauttaa joukon, joka sisältää kaikkien valmisteltujen kanavien SelectionKey-objektit.
  • wakeup(): Keskeytys estettyselect()siirtää.

SelectionKeySe on valitsimien ja kanavien välinen yhteys. Se edustaa kanavan rekisteröintitilaa valitsimessa, mukaan lukien kanavat, valitsijat, kiinnostuneet tapahtumakokoelmat ja valmiit tapahtumakokoelmat.

3. Verkko-ohjelmointi

1. I/O:n estäminen

​Tämä on perinteisin I/O-malli Javassa perinteiset Socket- ja ServerSocket-API:t perustuvat I/O:n estoon. Tässä tilassa, kun säie aloittaa luku- tai kirjoitustoiminnon, säie estetään, kunnes I/O-toiminto on valmis. Jos lukutoimintoa varten ei ole luettavaa dataa tai kirjoitustoimintoa ei voida suorittaa heti loppuun, säie odottaa, kunnes toiminto on valmis.

Ominaisuudet:

  • Yksinkertainen ohjelmointimalli: Helppo ymmärtää ja toteuttaa.
  • Resurssien käyttö: Jokainen yhteys vaatii erillisen säikeen, mikä johtaa rajoitettuun määrään säikeitä ja suureen resurssien kulutukseen.
  • Suorituskyvyn rajoitukset: Korkean samanaikaisuuden skenaarioissa säikeiden vaihto ja kontekstin vaihtaminen ovat kalliita ja voivat helposti muodostua pullonkauloksi.

2. Ei-esto I/O

​Estoton I/O on osa Java NIO (New I/O) -kehystä, jonka avulla säikeet voivat aloittaa luku- ja kirjoitustoiminnot ilman, että niitä estetään. Jos lukutoimintoa varten ei ole luettavaa dataa tai kirjoitustoimintoa ei voida suorittaa heti loppuun, säiettä ei keskeytetä ja se voi jatkaa muiden tehtävien suorittamista.

Ominaisuudet:

  • joustavuus: Säikeet voivat käsitellä enemmän yhteyksiä, koska niitä ei ole estetty odottamassa I/O-toimintoja.
  • Lisääntynyt monimutkaisuus: Ohjelmoijan on tarkastettava tarkasti, onko toiminto suoritettu loppuun, mikä lisää ohjelmoinnin vaikeutta.
  • Suorituskyvyn parannuksia: Korkean samanaikaisuuden skenaarioissa säikeiden vaihdon aiheuttamaa lisäkustannuksia voidaan vähentää merkittävästi.

3. Multipleksointi

​Multipleksoinnilla on tarkoitus valvoa useita tiedostokuvaajia samanaikaisesti yhden säikeen kautta ja toimia vain kuvaajan kanssa, kun se on valmis (tavallisesti tarkoittaa, että tiedot ovat luettavissa tai kirjoituspuskuri on kirjoitettava). Javassa käytetään valitsimia multipleksoinnin toteuttamiseen.

Ominaisuudet:

  • Korkea samanaikaisuus: Yksi säie pystyy käsittelemään tuhansia yhteyksiä, mikä parantaa huomattavasti palvelimen suorituskykyä.
  • Tehokas: Vain kun I/O-toiminto on valmis, lanka herätetään tarpeettoman säikeenvaihdon välttämiseksi.
  • Resurssien säästäminen: Verrattuna estoon I/O, multipleksointimallin palvelimet voivat käyttää järjestelmäresursseja tehokkaammin.

Ilmoitus:

Käytännön sovelluksissa estostamatonta I/O:ta käytetään usein multipleksoinnin yhteydessä. Palvelin voi esimerkiksi käyttää valitsinta useiden SocketChannelien valvontaan. Kun SocketChannelilla on tietoja, joita voidaan lukea tai kirjoittaa, Selector ilmoittaa siitä palvelimelle, ja palvelin käsittelee tämän tietyn SocketChannelin estävällä tavalla.

4.NIO VS BIO

4.1 stream vs kanava

Javassa Stream ja Channel ovat kaksi erilaista tapaa käsitellä tietovirtoja. Ne kuuluvat Java-standardin IO-kirjastoon ja vastaavasti NIO-kirjastoon. Tässä on yksityiskohtainen vertailu kahdesta käsitteestä:

Striimaa

Stream on osa Javan standardia IO (blocking IO) -mallia, joka tarjoaa tavan lukea ja kirjoittaa tietoja peräkkäin. Stream on jaettu kahteen tyyppiin: InputStream ja OutputStream, joita käytetään tietojen lukemiseen ja kirjoittamiseen.Nämä virrat voivat olla tavuvirtoja (esimInputStream, OutputStream) tai merkkivirta (esimReader, Writer)。

Ominaisuudet:

  • Obstruktiivinen: Oletusarvoisesti Stream-toiminnot estävät, eli jos lukutoimintoa varten ei ole luettavaa dataa tai kirjoitustoimintoa ei voida suorittaa heti loppuun, kutsuva säie estetään, kunnes toiminto on valmis.
  • Yksisuuntaisuus: Jokaisella streamilla on suunta, joko vain luku tai kirjoitus.
  • automaattinen sammutus: Streamin käytön jälkeen sinun on yleensä soitettava siihenclose() tapa vapauttaa resursseja.Java 7:stä alkaen try-with-resources -käsky voi sulkea toteutuksen automaattisestiAutoCloseableKäyttöliittymäresurssit, mukaan lukien Stream.

kanava

Kanava on osa Java NIO (New IO) -mallia, joka tarjoaa korkeamman tason abstraktiota kuin Stream, mikä mahdollistaa tehokkaamman tietojenkäsittelyn. Kanavat voivat olla kaksisuuntaisia, mikä tarkoittaa, että niitä voidaan käyttää tietojen lukemiseen ja kirjoittamiseen.Pääkanavatyyppejä ovat mmFileChannelSocketChannelServerSocketChanneljaDatagramChannel

Ominaisuudet:

  • ei estä : Kanava voidaan määrittää estäväksi tai ei-esto-tilaan. Jos lukutoiminnolla ei ole estotilassa luettavaa dataa tai kirjoitustoimintoa ei voida suorittaa välittömästi loppuun, toiminto palaa välittömästi sen sijaan, että se lukitsee säikeen.
  • Puskuritoiminnot:Kanavatoiminnot suoritetaan aina puskurin kautta (Buffer Data luetaan kanavasta puskuriin tai kirjoitetaan puskurista kanavaan).
  • Multipleksointi: Kanavaa voidaan käyttää yhdessä Selectorin kanssa multipleksoinnin saavuttamiseksi, jolloin yksi säie voi valvoa useiden kanavien I/O-toimintoja ja parantaa samanaikaisia ​​prosessointiominaisuuksia.

Tee yhteenveto

  • Sovellettava kohtaus: Stream soveltuu paremmin pienempien tietojoukkojen tai yksinkertaisten tiedostotoimintojen käsittelyyn, kun taas Channel sopii paremmin suurten tietomäärien käsittelyyn, erityisesti verkkoviestintään ja suuriin tiedostotoimintoihin, koska se tarjoaa paremman suorituskyvyn ja paremmat samanaikaisuusominaisuudet.
  • Ohjelmoinnin monimutkaisuus: Streamin API on suhteellisen yksinkertainen ja helppokäyttöinen, kun taas kanavan ja NIO:n API ovat monimutkaisempia, mutta tarjoavat tehokkaampia toimintoja ja suuremman tehokkuuden.
  • Resurssienhallinta: Olipa kyseessä stream tai kanava, resursseja tulee hallita asianmukaisesti ja varmistaa, että ne suljetaan, kun niitä ei enää tarvita, jotta vältetään resurssivuodot.

4.2 IO-malli

Javassa I/O-toimintamallit voidaan luokitella kahden ulottuvuuden perusteella: synkroninen/asynkroninen ja estävä/ei-esto.

4.2.1 Synkroninen esto I/O

määritelmä : Synkroninen esto I/O on perinteisin I/O-malli. Tämä tarkoittaa, että säie ei voi suorittaa muita tehtäviä ennen kuin toiminto on valmis.

ominaisuudet

  • Yksinkertainen ja helppokäyttöinen, koodilogiikka on selkeä.
  • Jokainen I/O-toiminto vaatii yksinomaisen säikeen, joka ei sovellu korkean samanaikaisuuden skenaarioihin ja voi johtaa säieresurssien kulumiseen.
  • Yleisesti käytössäInputStreamOutputStreamSocketjaServerSocketnäkymä.

Esimerkki:

Käytä perinteistäInputStreamjaOutputStreamTiedostojen lukeminen ja kirjoittaminen:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class SyncBlockingIOExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt")) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

4.2.2 Synkroninen ei-esto I/O

määritelmä : Synkronisessa ei-estossa I/O:ssa säiettä ei lukita I/O-toiminnon kutsumisen jälkeen. Jos toimintoa ei voida suorittaa heti loppuun, menetelmä palaa välittömästi, yleensä palauttaen erikoisarvon (kuten -1 tai 0) tai heittämällä poikkeuksen osoittamaan, että toimintoa ei ole suoritettu loppuun.

ominaisuudet

  • Toiminnon tilaa on pollattava, kunnes toiminto on valmis.
  • Parempi säikeen käyttöaste, koska säikeet voivat suorittaa muita tehtäviä odottaessaan I/O:ta.
  • Toteutus on monimutkaisempaa, ja sen on käsiteltävä kyselyitä ja tilatarkistuksia.
  • Perustuu Java NIO:aanChannelsjaBuffers, soittamallaconfigureBlocking(false)Aseta kanava estotilaan.

Esimerkki:

NIO:n käyttöFileChannelLukemisen ja kirjoittamisen estäminen:

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

public class SyncNonBlockingIOExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt");
             FileChannel inChannel = fis.getChannel();
             FileChannel outChannel = fos.getChannel()) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            inChannel.configureBlocking(false);
            while (inChannel.read(buffer) > 0) {
                buffer.flip();
                outChannel.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

4.2.3 Synkroninen multipleksointi I/O

määritelmä: Synkronisen multipleksoidun I/O-mallin käyttöSelector(valitsin) useiden seuraamiseenChannel tapahtuma.Kun lanka kutsuuSelector.select(), se estetään, kunnes niitä on vähintään yksiChannelTapahtumia (kuten luettavissa, kirjoitettavissa, yhteyspyyntö jne.) tapahtuu.

ominaisuudet

  • Antaa yhden säikeen hallita useitaChannel, parantaa samanaikaisuutta.
  • kulkeaSelectorjaSelectionKeyMekanismi, joka pystyy käsittelemään tehokkaasti useita samanaikaisia ​​yhteyksiä.
  • Soveltuu verkkopalvelinskenaarioihin, kuten verkkopalvelimiin ja chat-palvelimiin.
  • Perustuu Java NIO -kehykseen.

Esimerkki:

NIO:n käyttöFileChannelLukemisen ja kirjoittamisen estäminen:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class SyncMultiplexingIOExample {
    public static void main(String[] args) throws IOException {
        try (Selector selector = Selector.open();
             ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {
            serverSocketChannel.socket().bind(new InetSocketAddress(8080));
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
                if (selector.select() > 0) {
                    Set<SelectionKey> keys = selector.selectedKeys();
                    for (SelectionKey key : keys) {
                        if (key.isAcceptable()) {
                            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                            SocketChannel clientChannel = ssc.accept();
                            clientChannel.configureBlocking(false);
                            clientChannel.register(selector, SelectionKey.OP_READ);
                        }
                    }
                    keys.clear();
                }
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

4.2.4 Asynkroninen ei-esto I/O

määritelmä : Asynkronisessa ei-estossa I/O-mallissa säie palaa välittömästi I/O-toiminnon aloittamisen jälkeen odottamatta toiminnon valmistumista. Kun toiminto on valmis, säiettä ilmoitetaan asynkronisesti takaisinsoittotoiminnon tai tapahtumailmoituksen kautta.

ominaisuudet

  • Tehokkain I/O-malli, säikeitä ei ole estetty ollenkaan ja ne voivat suorittaa muita tehtäviä välittömästi.
  • kulkeaAsynchronousChannelKäyttöliittymä ja sen alaluokan toteutus, kutenAsynchronousFileChanneljaAsynchronousSocketChannel
  • Soveltuu korkean samanaikaisuuden ja korkean suorituskyvyn skenaarioihin, kuten suurten tietojen käsittelyyn ja suuren kuormituksen verkkopalvelimiin.
  • Java 7 esitteli asynkronisen ei-estoisen I/O-mallin.

Esimerkki:

NIO:n käyttöAsynchronousFileChannelSuorita asynkroninen tiedostojen lukeminen ja kirjoittaminen:

import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;

public class AsyncNonBlockingIOExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        AsynchronousFileChannel inChannel = AsynchronousFileChannel.open(Paths.get("input.txt"), StandardOpenOption.READ);
        AsynchronousFileChannel outChannel = AsynchronousFileChannel.open(Paths.get("output.txt"), StandardOpenOption.WRITE);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        CountDownLatch latch = new CountDownLatch(1);
        inChannel.read(buffer, 0, buffer, 0, (channel, result) -> {
            buffer.flip();
            outChannel.write(buffer, 0, buffer, 0, null);
            latch.countDown();
        });
        latch.await();
        inChannel.close();
        outChannel.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Huomautus: Asynkroninen malli vaatii tukea taustalla olevalta käyttöjärjestelmältä (ydin)

  • Windows-järjestelmät toteuttavat todellisen asynkronisen IO:n IOCP:n kautta
  • Asynkroninen IO Linux-järjestelmässä otettiin käyttöön versiossa 2.6, mutta sen taustalla oleva toteutus käyttää edelleen multipleksointia asynkronisen IO:n simuloimiseen, eikä suorituskykyetu ole.

4.2.5 Asynkroninen esto I/O

määritelmä : Teoriassa tätä mallia ei ole olemassa, koska "asynkroninen" tarkoittaa, että toiminto suoritetaan taustalla eikä säiettä ole estetty. Siksi asynkroninen esto I/O on ristiriitainen käsite, eikä sitä tule esiin käytännössä.

4.2.6 Yhteenveto

Sopivan I/O-mallin valitseminen on ratkaisevan tärkeää suorituskyvyn ja resurssienhallinnan kannalta. Korkean samanaikaisuuden skenaarioissa synkroniset estävät I/O-mallit tai synkroniset multipleksoidut I/O-mallit ovat yleisiä vaihtoehtoja skenaarioissa, jotka vaativat äärimmäistä suorituskykyä ja vastenopeutta, asynkroninen ei-esto-I/O-malli on ensimmäinen valinta.

4.3 Nolla kopiota

Zero-Copy -konsepti

​ Zero-copy-tekniikka tarkoittaa, että tiedonsiirron aikana paikasta toiseen tietoja ei tarvitse kopioida käyttäjätilan ja ydintilan välillä tai ainakin vähentää tällaisten kopioiden määrää, mikä parantaa tiedonsiirron tehokkuutta. järjestelmä. Perinteisissä I/O-toiminnoissa, kun dataa luetaan verkosta tai levyltä, se kopioidaan ensin ydintilan puskuriin ja sitten ydintilasta käyttäjätilan puskuriin. Päinvastoin, nollakopiossa data voidaan käsitellä suoraan ydintilassa tai siirtää suoraan ydintilasta verkkolaitteeseen, mikä vähentää prosessorin kopiointitoimintaa, vähentää järjestelmän ylikuormitusta ja parantaa tiedonsiirron tehokkuutta.

Nollakopion lähde

Nollakopion käsite ilmestyi ensimmäisen kerran käyttöjärjestelmän suunnittelussa, ja sen tavoitteena oli ratkaista perinteisten I/O-toimintojen tiedon kopioimisen aiheuttama suorituskyky pullonkaula. Varhaisissa tietokonejärjestelmissä kaikki I/O-toiminnot vaativat useita datakopioita käyttäjätilan ja ydintilan välillä. Tästä tuli vähitellen suorituskyvyn pullonkaula, kun nopeat verkot ja suuren kapasiteetin levyt yleistyivät.

Tärkeimmät tekniset kohdat

  • Suora I/O: Antaa sovellusten käyttää levylaitteita suoraan, ohittaen tiedostojärjestelmän välimuistimekanismin.
  • Muistikartoitus (MMAP): Yhdistä tiedostot muistiin, jotta tiedostotietoja voidaan käyttää kuten muistia, mikä vähentää kopioimista.
  • Lähetä tiedosto: Linux-järjestelmäkutsu, joka voi siirtää tietoja suoraan tiedostokuvauksesta toiseen välttäen välikopioita.
  • DMA (suora muistin käyttö): Laitteistotason tekniikka, joka mahdollistaa tietojen siirtämisen suoraan laitteen ja muistin välillä ilman prosessoria.

Käyttöönotto Javassa:

Java tukee nollakopiotekniikkaa NIO (New I/O) -kehyksen kautta. NIO esitteliFileChanneljaSocketChannel ja muut luokat, jotka tarjoavat tehokkaamman I/O-toiminnan. Erityisesti,FileChannel.transferTo()jaFileChannel.transferFrom()Menetelmillä voidaan siirtää tietoja suoraan tiedostokanavasta socket-kanavalle tai päinvastoin lataamatta dataa puskuriin, jolloin saadaan nollakopio.

Oletetaan esimerkiksi, että sinun on lähetettävä suuren tiedoston sisältö verkkoon. Perinteinen lähestymistapa on ensin lukea tiedoston sisältö puskuriin ja kirjoittaa puskurin sisältö verkkoon. Tämä sisältää kaksi kopiointitoimintoa: yksi levyltä puskuriin ja toinen puskurista verkkoon.käytön aikanatransferTo()Tätä menetelmää käytettäessä tiedot voidaan siirtää suoraan levyltä verkkoon ilman välipuskuria, mikä vähentää kopioiden määrää ja saavuttaa nollakopion.

Esimerkki ByteBufferista:

ByteBufferja muutBufferluokka (esimCharBufferShortBufferjne.) tarjoavat puskureita, jotka voidaan täyttää tai tyhjentää ilman, että käyttäjätilan ja ydintilan välillä tehdään kopiota.ByteBufferVoidaan käyttää suoraan tai epäsuorasti nollakopiotekniikassa:

  1. Suora puskuriByteBuffer.allocateDirect(size)LuotuByteBuffer Instanssit kartoitetaan suoraan fyysiseen muistiin Java-keon ohittaen.Kun tällaista puskuria verrataanFileChanneltaiSocketChannel Yhdessä käytettynä tiedot voidaan siirtää suoraan fyysisen muistin ja laitteiston välillä ilman lisäkopioita Java-keon kautta. Tämä mahdollistaa todellisen nollakopion joillakin alustoilla.
  2. käyttääFileChannel/transferTo()jatransferFrom(): Nämä menetelmät mahdollistavat tietojen tallentamisen suoraanFileChanneljaSocketChannelvälitetäänByteBuffer välittäjänä. Tämä tarkoittaa, että tietoja voidaan siirtää suoraan levyltä verkkoon tai päinvastoin ilman, että niitä tarvitsee kopioida käyttäjätilan ja ydintilan välillä.
  3. käyttääByteBuffer/wrap()menetelmäwrap()-menetelmän avulla voit kääriä olemassa olevan tavutaulukon tai muun puskurin aByteBuffer , joten tietoja ei tarvitse kopioida uuteen puskuriin. Tämä on hyödyllistä tietojen tarpeettoman kopioimisen välttämiseksi.
  4. käyttääByteBuffer/slice()menetelmäslice() menetelmä luo näkymän puskurista kopioimatta taustalla olevia tietoja.Tämä tarkoittaa, että suuriByteBufferJaa useisiin pienempiin puskureihin ilman tietojen kopioimista.

Yhdistä ByteBuffer FileChannelin kanssa:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class ZeroCopyExample {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            long transferred = fileChannel.transferTo(0, fileChannel.size(), System.out);
            System.out.println("Transferred bytes: " + transferred);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Ilmoitus:

On huomattava, että itse asiassa ei ole olemassa täydellistä nollakopiota. Tässä mainittu nollakopio on vain itse sovelluksellemme, jolla ei ole käyttäjätason kopiota. Mutta jopa käyttäjätasolla on mahdotonta tehdä kopiointitoimintoja ollenkaan, vaan vähentää kopioita mahdollisimman paljon. Siksi voimme ymmärtää, että termi nollakopio viittaa itse asiassa datakopioiden määrän vähentämiseen. eikä se tarkoita, etteikö todellista kopiointitoimintoa olisi.