Sobes.tech
Middle

Kuidas salvestatakse stringe Java keeles mällu?

sobes.tech AI

Vastus AI-lt

Java keeles on rida (String) muutumatu objekt. Selle väärtus on sümbolite jada.

Kuni Java 9-ni salvestas String sümboleid char[] massiivis. Iga sümbol võttis 2 baiti (UTF-16).

// Kuni Java 9
public final class String implements Serializable, Comparable<String>, CharSequence {
    private final char value[]; // Rida sümbolid
    private final int offset;   // Algpositsioon
    private final int count;    // Sümbolite arv (pikkus)
    // ... teised väljad ja meetodid
}

Alates Java 9-st, mälu säästmiseks, võib String kasutada kas byte[] massiivi (ASCII/Latin-1 sümbolite jaoks) või char[] massiivi (UTF-16 sümbolite jaoks). Kodeeringu määramiseks kasutatakse coder lipukest.

// Alates Java 9-st
public final class String implements Serializable, Comparable<String>, CharSequence {
    private final byte[] value; // Sümbolid (`byte[]` või `char[]` sõltuvalt `coder`-ist)
    private final byte coder;   // Kodeering: 0 Latin-1 jaoks, 1 UTF-16 jaoks
    // ... teised väljad ja meetodid
}

Stringi literaalid (ja stringid, mis on loodud new String(...) abil) salvestatakse "kõlbulasse" (heap) mälu.

Stringi literaalid asuvad ka "String Pool"-s, mis asub PermGen (enne Java 8) või MetaSpace (alates Java 8) mälu piirkonnas. Kui selline väärtus juba eksisteerib poolas, kasutatakse olemasolevat objekti.

String s1 = "hello"; // Loob "hello" String Poolis (kui seda veel pole), s1 viitab sellele
String s2 = "hello"; // s2 viitab samale "hello" objektile String Poolis
String s3 = new String("hello"); // Loob uue "hello" objekti heapis, s3 viitab sellele. "hello" võib olla ka String Poolis

Kuna stringid on muutumatud, siis nende väärtuse muutmine (näiteks ühendamine) põhjustab uue String objekti loomise mälu.