Speicherverwaltung in Java-Interviewfragen (+ Antworten)

Fragen im Vorstellungsgespräch zu Memory Management in Java (+ Antworten)

1. Einführung

In diesem Artikel werden einige Fragen zur Speicherverwaltung behandelt, die bei Java-Entwicklerinterviews häufig auftauchen. Memory Management ist ein Bereich, mit dem nicht so viele Entwickler vertraut sind.

Tatsächlich müssen sich Entwickler im Allgemeinen nicht direkt mit diesem Konzept befassen, da sich die JVM um die Details kümmert. Selbst erfahrene Entwickler haben möglicherweise keine genauen Informationen zur Speicherverwaltung zur Hand, es sei denn, etwas läuft ernsthaft schief.

Auf der anderen Seite sind diese Konzepte in Interviews weit verbreitet - also lasst uns gleich loslegen.

2. Fragen

Q1. Was bedeutet die Anweisung "Speicher wird in Java verwaltet"?

Speicher ist die Schlüsselressource, die eine Anwendung benötigt, um effektiv zu arbeiten, und wie jede andere Ressource ist sie knapp. Daher erfordert die Zuweisung und Freigabe zu und von Anwendungen oder verschiedenen Teilen einer Anwendung viel Sorgfalt und Überlegung.

In Java muss ein Entwickler jedoch nicht explizit Speicher zuweisen und freigeben - die JVM und insbesondere den Garbage Collector - hat die Aufgabe, die Speicherzuweisung zu handhaben, damit der Entwickler dies nicht tun muss.

Dies steht im Gegensatz zu Sprachen wie C, in denen ein Programmierer direkten Zugriff auf den Speicher hat und buchstäblich auf Speicherzellen in seinem Code verweist, wodurch viel Platz für Speicherlecks geschaffen wird.

Q2. Was ist Müllabfuhr und was sind ihre Vorteile?

Bei der Garbage Collection wird der Heap-Speicher überprüft, welche Objekte verwendet werden und welche nicht, und die nicht verwendeten Objekte werden gelöscht.

Ein in Gebrauch befindliches Objekt oder ein Objekt, auf das verwiesen wird, bedeutet, dass ein Teil Ihres Programms weiterhin einen Zeiger auf dieses Objekt verwaltet. Ein nicht verwendetes Objekt oder ein nicht referenziertes Objekt wird von keinem Teil Ihres Programms mehr referenziert. So kann der von einem nicht referenzierten Objekt verwendete Speicher zurückgewonnen werden.

Der größte Vorteil der Speicherbereinigung besteht darin, dass die manuelle Speicherzuweisung / -freigabe für uns entfällt, sodass wir uns auf die Lösung des vorliegenden Problems konzentrieren können.

Q3. Gibt es Nachteile der Speicherbereinigung?

Yes. Immer wenn der Garbage Collector ausgeführt wird, wirkt sich dies auf die Leistung der Anwendung aus. Dies liegt daran, dass alle anderen Threads in der Anwendung angehalten werden müssen, damit der Garbage Collector-Thread seine Arbeit effektiv ausführen kann.

Abhängig von den Anforderungen der Anwendung kann dies ein echtes Problem sein, das vom Client nicht akzeptiert werden kann. Dieses Problem kann jedoch durch geschickte Optimierung und Garbage-Collector-Tuning und Verwendung verschiedener GC-Algorithmen erheblich reduziert oder sogar beseitigt werden.

Q4. Was bedeutet der Begriff „Stop-The-World“?

Wenn der Garbage Collector-Thread ausgeführt wird, werden andere Threads angehalten, was bedeutet, dass die Anwendung vorübergehend angehalten wird. Dies ist analog zur Hausreinigung oder Begasung, bei der den Insassen der Zugang verweigert wird, bis der Vorgang abgeschlossen ist.

Abhängig von den Anforderungen einer Anwendung kann die Garbage Collection "stop the world" zu einem inakzeptablen Einfrieren führen. Aus diesem Grund ist es wichtig, die Garbage-Collector-Optimierung und die JVM-Optimierung durchzuführen, damit das aufgetretene Einfrieren zumindest akzeptabel ist.

Q5. Was sind Stapel und Haufen? Was ist in jeder dieser Speicherstrukturen gespeichert und wie hängen sie zusammen?

Der Stapel ist ein Teil des Speichers, der Informationen zu verschachtelten Methodenaufrufen bis zur aktuellen Position im Programm enthält. Es enthält auch alle lokalen Variablen und Verweise auf Objekte auf dem Heap, die in den aktuell ausgeführten Methoden definiert sind.

Diese Struktur ermöglicht es der Laufzeit, von der Methode zurückzukehren und die Adresse zu kennen, von der sie aufgerufen wurde, sowie alle lokalen Variablen nach dem Beenden der Methode zu löschen. Jeder Thread hat einen eigenen Stapel.

Der Heap ist eine große Speichermasse, die zur Zuordnung von Objekten vorgesehen ist. Wenn Sie ein Objekt mit dem Schlüsselwortnewerstellen, wird es auf dem Heap zugewiesen. Der Verweis auf dieses Objekt befindet sich jedoch auf dem Stapel.

Generations-Garbage-Collection kann lose als die Strategie definiert werden, die der Garbage-Collector verwendet, wenn der Heap in eine Reihe von Abschnitten namens Generationen unterteilt ist, von denen jeder Objekte entsprechend ihrem „Alter“ auf dem Heap enthält.

Immer wenn der Garbage Collector ausgeführt wird, wird der erste Schritt in diesem Prozess als Markierung bezeichnet. Hier erkennt der Garbage Collector, welche Speicherbereiche verwendet werden und welche nicht. Dies kann sehr zeitaufwändig sein, wenn alle Objekte in einem System gescannt werden müssen.

Je mehr Objekte zugewiesen werden, desto länger wird die Liste der Objekte, was zu einer immer längeren Speicherbereinigungszeit führt. Die empirische Analyse von Anwendungen hat jedoch gezeigt, dass die meisten Objekte nur von kurzer Dauer sind.

Bei der Speicherbereinigung von Generationen werden Objekte nach ihrem „Alter“ in Bezug auf die Anzahl der Speicherbereinigungszyklen gruppiert, die sie überstanden haben. Auf diese Weise verteilte sich der Großteil der Arbeit auf verschiedene kleinere und größere Sammelzyklen.

Heute sind fast alle Müllsammler Generationen. Diese Strategie ist so beliebt, weil sie sich im Laufe der Zeit als optimale Lösung erwiesen hat.

Q7. Beschreiben Sie ausführlich, wie die generelle Speicherbereinigung funktioniert

Um richtig zu verstehen, wie die Speicherbereinigung von Generationen funktioniert, ist es wichtig, zuerstremember how Java heap is structured zu verwenden, um die Speicherbereinigung von Generationen zu erleichtern.

Der Haufen ist in kleinere Räume oder Generationen aufgeteilt. Diese Räume sind Young Generation, Old oder Tenured Generation und Permanent Generation.

Dieyoung generation hosts most of the newly created objects. Eine empirische Untersuchung der meisten Anwendungen zeigt, dass die meisten Objekte schnell kurzlebig sind und daher bald zur Sammlung zugelassen werden. Neue Objekte treten daher hier ihre Reise an und werden erst nach Erreichen eines bestimmten „Alters“ in den Raum der alten Generation „befördert“.

Der Begriff“age” in der generationsbedingten Speicherbereinigungrefers to the number of collection cycles the object has survived.

Der Raum der jungen Generation ist weiter in drei Räume unterteilt: einen Eden-Raum und zwei Überlebensräume wie Survivor 1 (s1) und Survivor 2 (s2).

Dieold generation hosts objects thathave lived in memory longer than a certain “age”. Die Objekte, die die Müllabfuhr der jungen Generation überstanden haben, werden in diesen Raum befördert. Es ist in der Regel größer als die junge Generation. Da es größer ist, ist die Müllabfuhr teurer und kommt weniger häufig vor als bei der jungen Generation.

permanent generationor more commonly called, PermGen, contains metadata required by the JVM zur Beschreibung der in der Anwendung verwendeten Klassen und Methoden. Es enthält auch den Zeichenfolgenpool zum Speichern interner Zeichenfolgen. Es wird von der JVM zur Laufzeit basierend auf den von der Anwendung verwendeten Klassen aufgefüllt. Außerdem können hier Plattformbibliotheksklassen und -methoden gespeichert werden.

Erstensany new objects are allocated to the Eden space. Beide Überlebensfelder beginnen leer. Wenn der Eden-Bereich voll ist, wird eine kleine Speicherbereinigung ausgelöst. Referenzierte Objekte werden in das erste Überlebensfeld verschoben. Nicht referenzierte Objekte werden gelöscht.

Während des nächsten kleinen GC passiert dasselbe mit dem Eden-Raum. Nicht referenzierte Objekte werden gelöscht und referenzierte Objekte in einen Überlebensraum verschoben. In diesem Fall werden sie jedoch in das zweite Überlebensfeld verschoben (S2).

Außerdem wird das Alter von Objekten aus dem letzten kleineren GC im ersten Überlebensraum (S1) erhöht und zu S2 verschoben. Sobald alle überlebenden Objekte in S2 verschoben wurden, werden sowohl S1- als auch Eden-Felder gelöscht. Zu diesem Zeitpunkt enthält S2 Objekte mit unterschiedlichem Alter.

Beim nächsten kleinen GC wird der gleiche Vorgang wiederholt. Diesmal wechseln jedoch die Überlebensräume. Referenzierte Objekte werden sowohl von Eden als auch von S2 nach S1 verschoben. Überlebende Objekte sind gealtert. Eden und S2 werden gelöscht.

Nach jedem kleinen Speicherbereinigungszyklus wird das Alter jedes Objekts überprüft. Diejenigen, die ein bestimmtes willkürliches Alter erreicht haben, zum Beispiel 8, werden von der jungen Generation zur alten oder festen Generation befördert. Für alle nachfolgenden kleineren GC-Zyklen werden Objekte weiterhin in den Raum der alten Generation befördert.

Dies erschöpft den Prozess der Müllabfuhr in der jungen Generation ziemlich. Schließlich wird die alte Generation einer großen Müllabfuhr unterzogen, die diesen Raum aufräumt und verdichtet. Für jeden Haupt-GC gibt es mehrere Neben-GCs.

Q8. Wann kommt ein Objekt für die Garbage Collection in Frage? Beschreiben Sie, wie der Gc ein berechtigtes Objekt sammelt.

Ein Objekt ist für die Garbage Collection oder GC berechtigt, wenn es von keinem aktiven Thread oder über statische Verweise erreichbar ist.

Der einfachste Fall, in dem ein Objekt für die Garbage Collection in Frage kommt, ist, wenn alle Referenzen null sind. Zyklische Abhängigkeiten ohne externe Referenz sind ebenfalls für die GC geeignet. Wenn also Objekt A auf Objekt B und Objekt B auf Objekt A verweist und keine andere Live-Referenz vorhanden ist, können sowohl Objekt A als auch B für die Speicherbereinigung verwendet werden.

Ein anderer offensichtlicher Fall ist, wenn ein übergeordnetes Objekt auf null gesetzt ist. Wenn ein Küchenobjekt intern auf ein Kühlschrankobjekt und ein Spülbeckenobjekt verweist und das Küchenobjekt auf Null gesetzt ist, können sowohl der Kühlschrank als auch das Spülbecken zusammen mit der übergeordneten Küche Müll gesammelt werden.

Q9. Wie löst man die Garbage Collection aus Java-Code aus?

You, as Java programmer, can not force garbage collection in Java; Es wird nur ausgelöst, wenn JVM glaubt, dass eine Garbage Collection basierend auf der Größe des Java-Heapspeichers erforderlich ist.

Bevor ein Objekt aus dem Speicherbereinigungsthread entfernt wird, wird die Methode finalize () für dieses Objekt aufgerufen und die Möglichkeit geboten, alle erforderlichen Aufräumarbeiten durchzuführen. Sie können diese Methode auch für einen Objektcode aufrufen. Es gibt jedoch keine Garantie dafür, dass beim Aufrufen dieser Methode eine Garbage Collection erfolgt.

Darüber hinaus gibt es Methoden wie System.gc () und Runtime.gc (), mit denen eine Anforderung der Garbage Collection an JVM gesendet wird. Es kann jedoch nicht garantiert werden, dass die Garbage Collection durchgeführt wird.

Q10. Was passiert, wenn nicht genügend Speicherplatz für die Speicherung neuer Objekte vorhanden ist?

Wenn in Heap kein Speicherplatz zum Erstellen eines neuen Objekts vorhanden ist, gibt Java Virtual MachineOutOfMemoryError oder genauerjava.lang.OutOfMemoryError heap space. aus

Q11. Ist es möglich, ein Objekt, das für die Speicherbereinigung in Frage kam, wiederzubeleben?

Wenn ein Objekt für die Speicherbereinigung in Frage kommt, muss der GC die Methodefinalizeausführen. Diefinalize-Methode wird garantiert nur einmal ausgeführt, daher kennzeichnet der GC das Objekt als finalisiert und gibt ihm eine Pause bis zum nächsten Zyklus.

In derfinalize-Methode können Sie ein Objekt technisch „wiederbeleben“, indem Sie es beispielsweise einemstatic-Feld zuweisen. Das Objekt wird wieder lebendig und kann nicht mehr für die Garbage Collection verwendet werden, sodass der GC es im nächsten Zyklus nicht mehr einsammelt.

Das Objekt würde jedoch als finalisiert markiert, sodass die finalize-Methode nicht aufgerufen würde, wenn es wieder in Frage käme. Im Wesentlichen können Sie diesen „Auferstehungstrick“ nur einmal für die Lebensdauer des Objekts aktivieren. Beachten Sie, dass dieser hässliche Hack nur verwendet werden sollte, wenn Sie wirklich wissen, was Sie tun. Wenn Sie diesen Trick jedoch verstehen, erhalten Sie einen Einblick in die Funktionsweise des GC.

Q12. Beschreiben Sie starke, schwache, weiche und Phantomreferenzen und ihre Rolle bei der Speicherbereinigung.

So wie der Speicher in Java verwaltet wird, muss ein Ingenieur möglicherweise in kritischen Anwendungen so viel Optimierung wie möglich durchführen, um die Latenz zu minimieren und den Durchsatz zu maximieren. Ähnlich wieit is impossible to explicitly control when garbage collection is triggered in der JVM,it is possible to influence how it occurs as regards the objects we have created.

Java stellt uns Referenzobjekte zur Verfügung, um die Beziehung zwischen den von uns erstellten Objekten und dem Garbage Collector zu steuern.

Standardmäßig wird jedes Objekt, das wir in einem Java-Programm erstellen, stark von einer Variablen referenziert:

StringBuilder sb = new StringBuilder();

Im obigen Snippet erstellt das Schlüsselwortnew ein neuesStringBuilder-Objekt und speichert es auf dem Heap. Die Variablesb speichert dannstrong reference in diesem Objekt. Für den Garbage Collector bedeutet dies, dass das jeweiligeStringBuilder-Objekt aufgrund einer starken Referenz vonsb überhaupt nicht zur Erfassung berechtigt ist. Die Geschichte ändert sich nur, wenn wirsbwie folgt aufheben:

sb = null;

Nach dem Aufruf der obigen Zeile kann das Objekt abgeholt werden.

Wir können diese Beziehung zwischen dem Objekt und dem Garbage Collector ändern, indem wir es explizit in ein anderes Referenzobjekt einschließen, das sich im Paket vonjava.lang.refbefindet.

Einsoft reference kann für das obige Objekt wie folgt erstellt werden:

StringBuilder sb = new StringBuilder();
SoftReference sbRef = new SoftReference<>(sb);
sb = null;

Im obigen Snippet haben wir zwei Verweise auf das ObjektStringBuildererstellt. Die erste Zeile erzeugt einstrong referencesb und die zweite Zeile erzeugt einsoft referencesbRef. Die dritte Zeile sollte das Objekt für die Sammlung geeignet machen, aber der Garbage Collector wird die Sammlung aufgrund vonsbRef verschieben.

Die Geschichte wird sich nur ändern, wenn der Speicher knapp wird und die JVM kurz davor steht, einenOutOfMemory-Fehler auszulösen. Mit anderen Worten, Objekte mit nur weichen Referenzen werden als letzter Ausweg zur Wiederherstellung des Speichers gesammelt.

Einweak reference kann auf ähnliche Weise mit der KlasseWeakReference erstellt werden. Wennsb auf null gesetzt ist und das ObjektStringBuilder nur eine schwache Referenz hat, hat der Garbage Collector der JVM absolut keine Kompromisse und sammelt das Objekt sofort im nächsten Zyklus.

Einphantom reference ähnelt einer schwachen Referenz und ein Objekt mit nur Phantomreferenzen wird ohne Wartezeit gesammelt. Phantomverweise werden jedoch in die Warteschlange gestellt, sobald ihre Objekte gesammelt wurden. Wir können die Referenzwarteschlange abfragen, um genau zu wissen, wann das Objekt gesammelt wurde.

Q13. Angenommen, wir haben eine kreisförmige Referenz (zwei Objekte, die sich gegenseitig referenzieren). Könnte ein solches Objektpaar für die Müllabfuhr in Frage kommen und warum?

Ja, ein Paar von Objekten mit einem Zirkelverweis kann zur Garbage Collection zugelassen werden. Dies liegt daran, wie der Garbage Collector von Java Zirkelverweise verarbeitet. Objekte werden nicht als live betrachtet, wenn sie einen Verweis auf sie haben, sondern wenn sie durch Navigieren im Objektdiagramm ab einem bestimmten Garbage Collection-Stammverzeichnis (einer lokalen Variablen eines Live-Threads oder eines statischen Felds) erreichbar sind. Wenn ein Paar von Objekten mit einem Zirkelverweis von keinem Stamm aus erreichbar ist, wird es als für die Garbage Collection geeignet angesehen.

Q14. Wie werden Strings im Speicher dargestellt?

Die Instanz vonStringin Java ist ein Objekt mit zwei Feldern: einem Feld vonchar[] valueund einem Feld vonint hash. Das Feldvalue ist ein Array von Zeichen, die die Zeichenfolge selbst darstellen, und das Feldhash enthält diehashCode einer Zeichenfolge, die mit Null initialisiert wird und während der erstenhashCode() berechnet wird seitdem anrufen und zwischengespeichert. Als merkwürdiger Randfall muss einhashCode eines Strings, wenn er einen Nullwert hat, jedes Mal neu berechnet werden, wennhashCode() aufgerufen wird.

Wichtig ist, dass die Instanz vonStringunveränderlich ist: Sie können das zugrunde liegende Array vonchar[]nicht abrufen oder ändern. Ein weiteres Merkmal von Zeichenfolgen besteht darin, dass die statischen konstanten Zeichenfolgen geladen und in einem Zeichenfolgenpool zwischengespeichert werden. Wenn Ihr Quellcode mehrere identischeString-Objekte enthält, werden diese zur Laufzeit alle durch eine einzelne Instanz dargestellt.

Q15. Was ist ein Stringbuilder und was sind seine Anwendungsfälle? Was ist der Unterschied zwischen dem Anhängen eines Strings an einen Stringbuilder und dem Verketten von zwei Strings mit einem + -Operator? Wie unterscheidet sich Stringbuilder von Stringbuffer?

StringBuilder ermöglicht das Bearbeiten von Zeichenfolgen durch Anhängen, Löschen und Einfügen von Zeichen und Zeichenfolgen. Dies ist eine veränderbare Datenstruktur im Gegensatz zur KlasseString, die unveränderlich ist.

Wenn zweiString Instanzen verkettet werden, wird ein neues Objekt erstellt und Zeichenfolgen werden kopiert. Dies kann einen enormen Speicherbereinigungsaufwand verursachen, wenn eine Zeichenfolge in einer Schleife erstellt oder geändert werden muss. StringBuilder ermöglicht eine wesentlich effizientere Handhabung von String-Manipulationen.

StringBuffer unterscheidet sich vonStringBuilder darin, dass es threadsicher ist. Wenn Sie eine Zeichenfolge in einem einzelnen Thread bearbeiten müssen, verwenden Sie stattdessenStringBuilder.

3. Fazit

In diesem Artikel haben wir einige der häufigsten Fragen behandelt, die in Interviews mit Java-Ingenieuren häufig auftreten. Fragen zur Speicherverwaltung werden meistens für Senior Java Developer-Kandidaten gestellt, da der Interviewer erwartet, dass Sie nicht-triviale Anwendungen erstellt haben, die häufig von Speicherproblemen geplagt werden.

Dies sollte nicht als eine erschöpfende Liste von Fragen behandelt werden, sondern vielmehr als eine Startrampe für die weitere Forschung. Wir wünschen Ihnen zum Beispiel viel Erfolg bei bevorstehenden Interviews.