Sobes.tech
Middle

Ինչպես են տողերը պահվում հիշողության մեջ Java-ում?

sobes.tech AI

Պատասխան AI-ից

Java-ում, տող (String) անփոփոխ օբյեկտ է: Նրա արժեքը ներկայացվում է նիշերի հաջորդականությամբ:

Java 9-ға дейін, String պահում էր նիշերը char[] զանգվածում: Ամեն նիշը զբաղեցնում էր 2 բայթ (UTF-16):

// Java 9-ға дейін
public final class String implements Serializable, Comparable<String>, CharSequence {
    private final char value[]; // Տողը բաղկացած նիշերից
    private final int offset;   // Սկզբնական տեղափոխում
    private final int count;    // Նիշերի քանակ (երկարություն)
    // ... այլ դաշտեր և մեթոդներ
}

Java 9-ից սկսած, հիշողության խնայողության համար, String կարող է օգտագործել կամ byte[] զանգված (ASCII/Latin-1 նիշերի համար), կամ char[] զանգված: Կոդավորումը որոշվում է coder նշակետով:

// Java 9-ից սկսած
public final class String implements Serializable, Comparable<String>, CharSequence {
    private final byte[] value; // Տողը նիշեր (byte[] կամ char[] ըստ coder-ի)
    private final byte coder;   // Կոդավորում՝ 0 Latin-1, 1 UTF-16
    // ... այլ դաշտեր և մեթոդներ
}

Տողային լիտերալները (թույլատրված նիշեր) և new String(...) օպերատորով ստեղծված տողերը պահվում են "heap"-ում:

Տողային լիտերալները նաև տեղադրվում են "String Pool"-ում, որը գտնվում է հիշողության PermGen տարածքում (Java 8-ից առաջ) կամ MetaSpace-ում (Java 8-ից հետո): Եթե նույն արժեքով տող արդեն գոյություն ունի պուլում, օգտագործվում է առկա օբյեկտի հղումը:

String s1 = "hello"; // Ստեղծում է "hello"-ն String Pool-ում (եթե դեռ չկա), s1 հղում է դրա վրա
String s2 = "hello"; // s2 հղում է նույն օբյեկտին, ինչ s1
String s3 = new String("hello"); // Ստեղծում է նոր օբյեկտ "hello" heap-ում, s3 հղում է դրա վրա. "hello" կարող է լինել String Pool-ում

Քանի որ տողերը անփոփոխ են, տողի արժեքի փոփոխությունը (օրինակ, միակցում) հանգեցնում է նոր String օբյեկտի ստեղծման հիշողության մեջ։