Warum Caching-Werte der Integer-Klasse im Bereich von -128 bis 127?

Lesezeit: 3 Minuten

Warum Caching Werte der Integer Klasse im Bereich von 128 bis 127
DnR

In Bezug auf meine vorherige Frage: Warum ergeben == Vergleiche mit Integer.valueOf(String) unterschiedliche Ergebnisse für 127 und 128? , Wir wissen das Integer class hat einen Cache, der Werte zwischen speichert -128 und 127.

Fragt sich nur, warum zwischen -128 und 127?

Integer.valueOf()-Dokumentation erklärte, dass es Zwischenspeichern häufig angeforderter Werte . Aber Werte zwischen -128 und 127 werden häufig echt nachgefragt? ich dachte häufig angeforderte Werte sind sehr subjektiv.

Gibt es einen möglichen Grund dafür?

Aus der Dokumentation heißt es auch: ..und kann andere Werte außerhalb dieses Bereichs zwischenspeichern.

Wie kann dies erreicht werden?

  • Bezüglich der Dokumentation: Oracle deckt nur ihren Hintern ab, falls sie sich entscheiden, das Verhalten später zu ändern. Sie können beispielsweise entscheiden, dass Java 9 von -1024 bis 1023 zwischenspeichert. Die Botschaft lautet, verlassen Sie sich nicht darauf, dass der Cache eine bestimmte Ganzzahl enthält oder nicht enthält.

    – Dawud ibn Kareem

    3. Januar 2014 um 5:18 Uhr

  • Ich nehme an, Sie schleifen viel öfter von 0 nach X als von 13476 nach Y. Sie müssen entschieden haben, dass auch negative Werte enthalten sein sollten und -128 -> 127 für ein vorzeichenbehaftetes Byte sinnvoll ist.

    – Jeroen Vannevel

    3. Januar 2014 um 5:21 Uhr

  • Wird das Schleifen nicht fast immer mit primitiven Ints durchgeführt – nicht mit Boxed Integers? Caching entfällt.

    – bradvido

    3. Januar 2014 um 21:45 Uhr

  • Der Cache ist eine reine Leistungssache. Solange es für Sie kein Leistungsproblem verursacht, sollte es Ihnen egal sein, welcher Bereich zwischengespeichert wird. (Es wäre der Gipfel der Torheit, in Ihren Code eine Abhängigkeit vom Integer-Caching einzubauen.)

    – Heiße Licks

    6. Januar 2014 um 3:50 Uhr

  • @JohnR es ist in der Java-Sprachspezifikation enthalten, siehe Assylias-Antwort unten.

    – Zac Thompson

    9. Januar 2014 um 22:47 Uhr

1646174830 807 Warum Caching Werte der Integer Klasse im Bereich von 128 bis 127
Assyrien

Ich frage mich nur, warum zwischen -128 und 127?

Ein größerer Bereich von ganzen Zahlen dürfen zwischengespeichert werden, aber zumindest die zwischen -128 und 127 Muss zwischengespeichert werden, da dies von der vorgeschrieben ist Java-Sprachspezifikation (Hervorhebung von mir):

Wenn der umrahmte Wert p wahr, falsch, ein Byte oder ein Zeichen im Bereich \u0000 bis \u007f oder ist eine int oder kurze Zahl zwischen -128 und 127 (einschließlich), dann seien r1 und r2 die Ergebnisse von zwei beliebigen Boxing-Konvertierungen von p. Es gilt immer r1 == r2.

Die Begründung für diese Anforderung wird im selben Absatz erläutert:

Im Idealfall würde das Boxen eines gegebenen primitiven Werts p immer eine identische Referenz ergeben. In der Praxis ist dies unter Verwendung vorhandener Implementierungstechniken möglicherweise nicht machbar. Die obigen Regeln sind ein pragmatischer Kompromiss. Die letzte Klausel oben erfordert, dass bestimmte gemeinsame Werte immer in nicht unterscheidbare Objekte eingepackt werden. […]

Dadurch wird sichergestellt, dass das Verhalten in den meisten Fällen das gewünschte ist, ohne dass eine übermäßige Leistungseinbuße entsteht, insbesondere bei kleinen Geräten. Weniger speicherbegrenzte Implementierungen könnten beispielsweise alle char- und short-Werte sowie int- und long-Werte im Bereich von -32 KB bis +32 KB zwischenspeichern.


Wie kann ich andere Werte außerhalb dieses Bereichs zwischenspeichern?

Du kannst den … benutzen -XX:AutoBoxCacheMax JVM-Option, die in der Liste nicht wirklich dokumentiert ist verfügbaren Hotspot-JVM-Optionen. Es wird jedoch erwähnt in die Kommentare in der Integer Klasse um Zeile 590:

Die Größe des Caches kann durch die gesteuert werden -XX:AutoBoxCacheMax=<size> Möglichkeit.

Beachten Sie, dass dies implementierungsspezifisch ist und möglicherweise auf anderen JVMs verfügbar ist oder nicht.

  • Dies ist die vollständige und beste Antwort – die Frage verwechselt den Bereich von -128 bis 127 mit den “häufig angeforderten Werten”, obwohl sie tatsächlich unterschiedliche Gründe haben. -128 bis 127 werden zum Boxen zwischengespeichert. “Häufig angeforderte Werte” werden aus Leistungsgründen zwischengespeichert.

    – Zac Thompson

    9. Januar 2014 um 22:51 Uhr

  • @ZacThompson, danke für den Hinweis. Mein vorheriger Kommentar war nicht korrekt. Der Schlüsselsatz aus der Spezifikation ist “ein int … zwischen -128 und 127 (einschließlich), dann seien r1 und r2 die Ergebnisse von zwei beliebigen Boxing-Konvertierungen von p. Es ist immer der Fall, dass r1 == r2.” Wenn ich das richtig verstehe, schreibt die Spezifikation vor, dass Integer.valueOf(X) == Integer.valueOf(X) wobei -128 <= X <= 127.

    – Johannes R

    10. Januar 2014 um 14:59 Uhr

  • Dies ist die einzige Antwort auf den „Warum“-Teil der Frage, die etwas anderes bietet als „es ist die Standardeinstellung“. Diese Antwort ist jedoch nicht vollständig, da sie den „Wie“-Teil der Frage nicht anspricht. Wenn Sie auf die Antworten anderer auf XX:AutoBoxCacheMax verweisen und Informationen darüber hinzufügen, wie das Caching-Verhalten auf anderen Implementierungen der JVM gesteuert werden kann (oder angeben, welche JVM-Implementierungen Optionen zur Steuerung dieses Verhaltens haben), wäre dies eine vollständige Antwort.

    – Johannes R

    10. Januar 2014 um 15:21 Uhr

  • “In der Praxis ist dies mit bestehenden Implementierungstechniken möglicherweise nicht machbar.” Ich bekomme diese Zeile nicht. Kannst du es bitte erklären?

    – niiraj874u

    15. Mai 2014 um 8:46 Uhr

  • @ niiraj874u Die aktuelle Implementierung verwendet einen Cache, der sich im Speicher befindet – jede “kanonische” Ganzzahl wird in diesem Cache gespeichert. Das Zwischenspeichern aller Ganzzahlen würde also bedeuten, dass Sie möglicherweise bis zu 2 ^ 32 Ganzzahlen (= 15+ GB) im Speicher halten müssen, was selbst auf einem modernen Desktop-Computer unangemessen ist.

    – Assylias

    15. Mai 2014 um 9:32 Uhr

1646174830 233 Warum Caching Werte der Integer Klasse im Bereich von 128 bis 127
Evgeniy Dorofeev

-128 bis 127 ist die Standardgröße. Javadoc sagt aber auch, dass die Größe des Integer-Cache vielleicht kontrolliert durch die -XX:AutoBoxCacheMax=<size> Möglichkeit. Beachten Sie, dass nur der hohe Wert festgelegt wird, der niedrige Wert ist immer -128. Diese Funktion wurde in 1.6 eingeführt.

Warum -128 bis 127 – dies ist ein Byte-Wertebereich und es ist natürlich, ihn für einen sehr kleinen Cache zu verwenden.

  • wie wir das umsetzen können -XX:AutoBoxCacheMax=<size>?

    – DnR

    3. Januar 2014 um 5:35 Uhr

  • Führen Sie java -XX:AutoBoxCacheMax=256 aus … und Sie werden sehen, dass Integer.valueOf(256) == Integer.valueOf(256)

    – Evgeniy Dorofeev

    3. Januar 2014 um 5:35 Uhr


  • durch Laufen java -XX:AutoBoxCacheMax=256 in der Konsole habe ich Error:could not create the Java Virtual Machine

    – DnR

    3. Januar 2014 um 5:44 Uhr

  • versuchen Sie die Java-Version, es sollte 1.6 oder höher sein, meine 1.7 funktioniert OK

    – Evgeniy Dorofeev

    3. Januar 2014 um 5:50 Uhr


  • Richtig, das ist der Grund, warum javadoc sagt … kann kontrolliert werden … mein Java ist 64 Bit

    – Evgeniy Dorofeev

    3. Januar 2014 um 6:51 Uhr

Der Grund für das Zwischenspeichern kleiner Ganzzahlen liegt darin, dass viele Algorithmen kleine Ganzzahlen in ihren Berechnungen verwenden, sodass es sich tendenziell lohnt, den Aufwand für die Objekterstellung für diese Werte zu vermeiden.

Dann stellt sich die Frage, welche Ganzzahlen zwischengespeichert werden sollen. Noch einmal allgemein gesagt, die Häufigkeit, mit der konstante Werte verwendet werden, nimmt tendenziell ab, wenn der absolute Wert der Konstanten zunimmt – jeder verbringt viel Zeit mit den Werten 1 oder 2 oder 10, relativ wenige verwenden den Wert 109 sehr intensiv; Weniger haben eine Leistung, die davon abhängt, wie schnell man eine ganze Zahl für 722 erhalten kann. Java hat sich entschieden, 256 Slots zuzuweisen, die den Bereich eines vorzeichenbehafteten Bytewerts überspannen. Diese Entscheidung wurde möglicherweise durch die Analyse von damals existierenden Programmen getroffen, war aber genauso wahrscheinlich eine rein willkürliche Entscheidung. Es ist eine angemessene Menge an Speicherplatz zu investieren, es kann schnell darauf zugegriffen werden (Maske, um herauszufinden, ob der Wert im Bereich des Caches liegt, dann eine schnelle Tabellensuche, um auf den Cache zuzugreifen), und es wird definitiv die häufigsten Fälle abdecken.

Mit anderen Worten, ich denke, die Antwort auf Ihre Frage lautet: “Es ist nicht so subjektiv, wie Sie dachten, aber die genauen Grenzen sind größtenteils eine Faustregel … und experimentelle Beweise waren, dass es gut genug war. “

Warum Caching Werte der Integer Klasse im Bereich von 128 bis 127
die Prüfungszeit

Der maximale hohe ganzzahlige Wert, der zwischengespeichert werden kann, kann über die Systemeigenschaft konfiguriert werden, dh java.lang.Integer.IntegerCache.high(-XX:AutoBoxCacheMax) . Der Cache wird mit einem Array implementiert.

    private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }

    private IntegerCache() {}
}

Wenn Sie auf die Integer-Klasse stoßen und immer innerhalb des Bereichs von -128 bis 127 geboxt sind, ist es immer besser, das Integer-Objekt wie unten in einen Int-Wert umzuwandeln.

<Your Integer Object>.intValue()

905660cookie-checkWarum Caching-Werte der Integer-Klasse im Bereich von -128 bis 127?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy