Video 6-6: Speicherverbrauch von Java-Programmen
CS 210 – Algorithms and Data Structures (Summer 2026) · unit page
· YouTube
2026-05-18, 12:18
The transcript was generated automatically by YouTube's speech recognition and is offered as is. It may contain errors, in particular in concerning technical terms, names and formulas.
0:04 Wovon ich rede, ist der Speicherbedarf von äh diversen Konstrukten in Java. Den sollte man so grob im Hinterkopf behalten. Auch wenn Sie die Details äh für die Klausur nicht wissen müssen, äh ist es, glaube ich, ganz interessant über diese Sachen ein bisschen Bescheid zu wissen. Und um das ähm konkret zu machen, nehmen wir mal so eine Miniklasse, wie hier diese Dateeklasse, also ganz harmlose Java Klasse mit drei Feldern äh drei Ins. Ähm, ich verspreche Ihnen sozusagen, wenn Sie da Methoden hinzufügen, dann ändern die an dem Speicherplatz pro Instanz der Klasse nichts, denn Methoden werden einmal für alle Objekte gemeinsam gespeichert, also einmal pro Klasse, nicht einmal pro Objekt.
0:56 Äh, alles andere ist sozusagen in Java dann uniform. Äh, jedes Objekt hat die Kapazität ähm Methoden zu haben und ob sie die dann tatsächlich definiert oder nicht, ändert am Speicherplatz pro Objekt, pro Instanz dann tatsächlich nichts.
1:15 Ist wieder so eine Frage, die Sie gar nicht wissen können, wenn Sie nicht schon irgendwie sich mal damit beschäftigt haben. Ähm, mag im allerletzten Detail ein bisschen platformabhängig sein, aber wenig, weil Java doch vieles ähm versucht, ein bisschen Plattform unabhängig zu kapseln. äh sage ich gleich mal noch was dazu. Als grobes Modell ähm reicht alle mal, was wir uns gleich zusammen anschauen. Also, wir können es ja vielleicht den Spaß machen, einmal darf zu schauen, was sie so geantwortet haben. Quer durch die Bank, nicht wahr? äh Werden uns der Frage annäheren Stück für Stück. Erstmal so ein paar äh Basics dazu. Wo wovon reden wir? Wie messen wir Speicherplatz? Na ja, äh entweder in Bits oder in Bytes oder in Größen, in Vielfahen davon. Ein Bit ist eine Einheit, die entweder 0 oder ein ist. das das elementarste und äh in der Regel fassen wir in dem Computer acht Bits zu einem Bte zusammen und sprechen in der Größenordnung, warum warum Bites? Also warum genau acht hat wahrscheinlich hauptsächlich historische Gründe, aber warum geben wir in aller Regel äh Arbeitsspeicher in Bites an? Das liegt daran, dass das die kleinste adressierbare Einheit in den meisten Architekturen ist.
2:48 Obwohl wir auf Wörtern rechnen, den Begriff kennen Sie von Wordram ja schon in der Regel, also 64 Bit äh die wir sozusagen in einem in einem Zyklus, in einem Rechenschritt addieren oder multiplizieren und so weiter können, äh ist die kleinste adressierbare Einheit ein Bite, also 8 Bit. Deswegen ist das die übliche ähm Einheit, in der man Speicher angibt. Äh für Megabyte, Gigabyte kennen Sie natürlich. Was was immer so ein bisschen unklar ist, wenn man das nur so hinschreibt, ist sind das jetzt Zehner Potenzen oder zweier Potenzen. Also, ich habe ja gelernt, manchmal gibt es MB und es gibt MB. MB wäre dann ja, wieum war es? Weiß es jemand? Also es ist entweder eine Million oder 220, was ja ein bisschen mehr als eine Million ist, wenn wir noch nicht viel. Und eins war das eine, eins war das andere. Und da ich mir nicht merken kann, welches welches ist, ist die Notation auch ziemlich nutzlos.
3:48 Also im im Detail, sie merken das in der Regel, weil Speicherhersteller gerne äh diese Darstellung verwenden, aber die Betriebssysteme diese, dass ihre USB-Sticks immer ein bisschen kleiner aussehen, als auf der Packung steht. Äh, das liegt nur daran im Wesentlichen. Na gut, also insbesondere auf einer 64 Bit Maschine ist jeder Pointer oder jeder Referenz in Java 8 byte lang, weil das die ähm Menge an Bits ist, mit der man Speicher adressieren kann. Äh unter der Haube ist das so ein bisschen nicht immer hundertprozentig wahr und auch in Java ist es manchmal so, dass ähm je nach Implementierung die gekürzt werden. Die Hardwareadressen für Arbeitsspeicher sind auch selten volle 64 Bit, weil normale Maschinen von Supercomputern abgesehen auch so viel Speicher eh nie eingebaut haben können. Äh die arbeiten dann oft mit einer geringeren Anzahl bitte, aber das ist wegabstrahiert vom Betriebssystem. Für den Speicherplatz für einen Pointer muss man trotzdem in der Regel mit 8 by rechnen.
4:56 Das ist die erste äh Lektion. Für die anderen primitiven Typen in Java ist relativ klar definiert, wie groß sie sind und das ist auch ihr Speicherbedarf. Einzige Ausnahme ist, dass ein Booli eigentlicher ein einzelnes Bit wäre oder nur die Werte wahr falsch kennt. Repräsentiert wird es aber als ein Bald aus dem Grund, den ich schon genannt habe, dass das die kleinste adressierbare Speichereinheit ist. Speichereffizienter wäre es natürlich, diese Bits in ein 8 Bits in ein Bte zu packen. Dann könnte man mehr davon unterbringen im gleichen Speicher. Acht mal so viele eben. Aber es wäre langsamer auf diese Bits zuzugreifen. Und wenn Sie also in Java nichts anders anderes sagen und ein boolian Array anlegen, dann ist das jeweils ein Bte mit der Annahme, dass in der Regel Schnelligkeit wichtiger ist als Speichereffizienz.
5:54 All die anderen Typen sind so groß, wie sie per Spezifikation Bits haben. Äh, wenn Sie Arrays anlegen, dann haben sie im Wesentlichen den Speicherplatz für diese Objekte. Also N double sind 8N byte, weil ein Dou 8 bytte sind. Aber es gibt noch so einen konstanten Overhead pro Array für Verwaltungs äh Information. Da wird unter anderem die Länge dabei sein. Das sind 8 Bitte davon. Was die anderen 16 sind, müsste man nachgucken. Äh mindestens eins ist für die Methoden, die Arrays ja auch haben. Auch Arrays sind Objekte, wissen Sie. Äh das ist sozusagen der Overhead, der dazu kommt. Für zweidimensionale Arrays gilt um und bei das gleiche, aber es gibt ja eigentlich keine zweidimensionalen Arrays in Java, sondern ein zweidimension ein Array hier. Double Array Array ist einfach ein Array von Double Arrays. Dementsprechend gilt für jeden Eintrag, was hier oben steht und für das Ganze gilt noch mal acht mal, weil jeder Eintrag von dem äußeren Double Array Array ein Pointer auf ein Double Array ist.
7:12 Gut, deswegen hier nur als Tilde Asymptotik angegeben. Wenn Sie es präzise ausrechnen, haben Sie einen linearen Anteil in der einen Dimension, der nur der die Anzahl Pointer hat, aber der dominante Teil ist eben die einzelnen Einträge für alle Zahlen.
7:33 Dann kommen wir auch schon zu Objekten. Und hier ist genau dieses Beispiel, was wir eben hatten. Äh, für jede Instanz gibt es immer einen konstanten Overhead von 16 Bitte. Ähm, das ist im Wesentlichen, also eins ist eine Referenz auf die Klasse und darüber auch ähm für Dynamic Dispatch einen Zeiger auf die Virtual Function Tables in nach C++ äh Sprache. Also, welche Methoden muss ich aufrufen? Dafür ist eins da. Ähm, für die anderen acht Bit fällt mir gerade nicht ein, wofür die gut sein könnten. Äh, nicht so wichtig. ähm kann man aber auf jeden Fall nachmessen. Referenzen sind immer acht Ball groß und ansonsten gibt's noch diese wichtige Eigenschaft, dass Objekte immer so aufgestockt werden mit ungenutztem Speicher, äh dass sie mit Vielfaches von 8 Bit belegen. Das ist um sicherzustellen, dass man die Objekte äh effizient laden kann, ohne dass sie mitten in dem Wort anfangen. wieder eine Optimierung, um äh den Speicherzugriff zu beschleunigen. Das heißt, für unser Beispiel haben wir diese 16 Bte an Overhead. Wir haben 12 Bte für die äh 3 ins und weil 12 und 16 ähm was ist 28, kein Vielfaches von 8. haben wir noch vier Bitte Padding, die einfach verfallen und die Gesamtgröße ist also 32.
9:21 für das, dass wir im Wesentlichen nur 12 äh Bytes Payload haben, relativ verschwenderisch, was ein bisschen zeigt, warum Java nicht unbedingt immer äh die effizienteste, die speichereffizienteste Art ist, Dinge zu implementieren.
9:40 Gut, ich kann sie ja auch noch hier mal freischalten. ähm der Vollständigkeit halber kann man das dann noch mal für die Aufnahme hier mit reinblenden. Äh also 12 Bald Bite ist eine durchaus sinnvolle äh Größe, aber leider ist der Overhead deutlich größer.
10:06 Hier ist noch mal eine Zusammenfassung von im Wesentlichen diesen äh einzelnen Folien, die davorkommen. Ähm bei Arrays ist manchmal die Frage, wenn das Arrays von Referenzen sind, zähle ich jetzt die Objekte, auf die diese Arrays zeigen, da beim Array mit oder zähle ich dies separat? Das ist jetzt keine theoretische Frage. Das ist äh eine Frage, wie sie wie sie die Buchhaltung vornehmen, wem sie das zuschlagen, damit man es nicht doppelt zählt. Äh hier noch mal ein komplizierteres Beispiel aus dem Union Find Kapitel. äh genau die Implementierung, die da verwendet wurde. Ähm da hatten wir eine Klasse, die zwei Arrays speichert und ein weiteres intamskomponenten.
10:55 Und dann kann man eben ausrechnen, was das Ding insgesamt an Speicherplatz benötigt. einmal ein Overhead für das Objekt dieser Klasse, dann habe ich die Beiträge der Arrays und auch hier wieder Padding für die präzise Gesamtzahl an Bites.
11:17 Wie erwähnt, die Details und die Zahlen halte ich für hilfreich nachgucken zu können, aber nicht essentiell für Prüfung in unserem Modul. Aber ich wollte es Ihnen nicht vorenthalten, dass Sie im Prinzip relativ einfach abschätzen können, wie viel Speicherplatz so ein Java Programm braucht.
11:34 Damit sind wir am Ende von diesem Kapitel. Wir haben gesehen, dass wir Laufzeitexperimente verwenden können, um präzise zu ver äh zu verstehen, was auf einer bestimmten Maschine passiert und eben vorhersagen zu machen für größere Eingaben, die wir vielleicht nicht ohne weiteres laufen lassen wollen. Wenn wir verstehen wollen, warum ein Algorithmus so oder so schnell ist, dann kommen wir meistens um eine mathematische Analyse nicht drum rum, die genauer offenbart, woher diese Laufzeit kommt. Und wir haben äh mit der wissenschaftlichen Methode einen eine Methologie an äh Methodik an der Hand, die uns da ähm näher an die Naturwissenschaften ranführt, als man das oft so gewohnt ist in der Informatik. Так.