MINT lernen

Speicherbedarf abschätzen

Wie viel Arbeitsspeicher belegen eine Million Messwerte — und was braucht der Algorithmus zusätzlich?

1

Was eine Reihung belegt

Neben der Zeit ist der Arbeitsspeicher die zweite knappe Ressource. Wie viel eine Reihung belegt, lässt sich schon an ihrer Deklaration ablesen.

Speicherbedarf der primitiven Datentypen in Java
Datentypbooleancharintlongdouble
Byte je Element1*2488
  • Einheiten:1 Byte = 8 Bit · 1 kB = 1 000 B · 1 MB = \(10^6\) B · 1 GB = \(10^9\) B.
  • Reihung:new int[n] belegt \(4n\) Byte plus einen kleinen festen Kopf (etwa 16 B) — also \(O(n)\).
  • Tabelle:new int[z][s]: \(z \cdot s\) Elemente, dazu je Zeile ein Kopf und eine Referenz.
  • Referenztypen:eine String[]-Reihung speichert nur Referenzen (4–8 B je Element); die Texte selbst liegen zusätzlich im Speicher.
  • * boolean:fachlich reicht 1 Bit; Java legt in Reihungen aber meist 1 Byte je Element an.
Herleitung:
\(1000 \cdot 1000 \cdot 8\,\text{B}\)
Elemente

new double[1000][1000]: eine Million Elemente zu je 8 Byte.

\(= 8\,000\,000\,\text{B}\)
ausrechnen

Das ist der Nutzspeicher der Tabelle.

\(1000 \cdot (16 + 8)\,\text{B} = 24\,000\,\text{B}\)
Verwaltung

Jede der 1000 Zeilen ist eine eigene Reihung mit Kopf; die äußere Reihung hält 1000 Referenzen.

\(\approx 8\,024\,000\,\text{B} \approx 8\,\text{MB}\)
Ergebnis

Die Verwaltung macht nur 0,3 % aus — für die Abschätzung genügt \(z \cdot s \cdot 8\) Byte.

2

Zusätzlicher Speicher

Beim Algorithmus zählt nicht die Eingabe selbst, sondern was er zusätzlich anlegt — in Abhängigkeit von \(n\).

  • In-place:nur einzelne Hilfsvariablen, unabhängig von \(n\): \(O(1)\) — Selection-, Insertion-, Bubblesort, lineare und binäre Suche.
  • Kopie:eine zweite Reihung gleicher Länge, z. B. eine sortierte Kopie neben dem Original: \(O(n)\).
  • Markierungsreihung:ein Feld je möglichem Wert: \(O(W)\) für den Wertebereich \(W\) — klein bei Noten 1–6, riesig bei Telefonnummern.
  • Rekursion:jeder offene Aufruf belegt Platz auf dem Stapelspeicher — die rekursive binäre Suche braucht \(O(\log n)\).

Ordne die Deklarationen nach ihrem Speicherbedarf — oben der kleinste, unten der größte. Ziehen, oder mit Leertaste aufnehmen, mit ↑/↓ verschieben und mit Leertaste ablegen. „Prüfen“ zeigt die Byte-Werte.

Wer belegt mehr Platz?

Halte fest: Der Speicherbedarf einer Reihung ist Anzahl der Elemente · Byte je Element. Eine Tabelle mit \(z\) Zeilen und \(s\) Spalten zählt wie eine Reihung mit \(z \cdot s\) Elementen.

  • Zeit gegen Speicher:doppelte Werte finden: paarweise vergleichen kostet \(O(n^2)\) Zeit und \(O(1)\) Speicher, eine Markierungsreihung \(O(n)\) Zeit und \(O(W)\) Speicher.
static boolean hatDoppelte(int[] a, int max) {  // alle Werte in 0 … max
    boolean[] gesehen = new boolean[max + 1];   // Zusatzspeicher: max + 1 Byte
    for (int x : a) {
        if (gesehen[x]) {
            return true;                        // x kam schon einmal vor
        }
        gesehen[x] = true;
    }
    return false;
}
Merke

Speicher einer Reihung \(\approx n \cdot\) Byte je Element (int 4, double 8) · Zusatzspeicher: in-place \(O(1)\), Kopie \(O(n)\), Markierungsreihung \(O(W)\)

3

Allgemeine Hinweise

Referenz ist nicht das Objekt

new String[1000] belegt nur Platz für 1000 Referenzen, alle zunächst null. Erst die Texte, die man zuweist, kosten den eigentlichen Speicher.

Größenordnung genügt

Kopf einer Reihung, Zählvariablen und Parameter sind konstant. Für die Abschätzung zählt nur, was mit \(n\) (oder dem Wertebereich) wächst.

Speicher hat eine harte Grenze

Zu langsam heißt „warten“, zu groß heißt Abbruch mit OutOfMemoryError. Eine Milliarde double-Werte braucht 8 GB — mehr als viele Rechner frei haben.

Videos