Geheugenbeheer in Java sollicitatievragen (+ antwoorden)

Dit artikel maakt deel uit van een reeks: • Interviewvragen over Java Collections

• Vragen over het Java Type System-interview

• Vragen over Java Concurrency-sollicitatiegesprekken (+ antwoorden)

• Vragen over Java-klassenstructuur en initialisatie

• Java 8 sollicitatievragen (+ antwoorden)

• Geheugenbeheer in Java interviewvragen (+ antwoorden) (huidig ​​artikel) • Java Generics interviewvragen (+ antwoorden)

• Vragen over Java Flow Control-interview (+ antwoorden)

• Interviewvragen over Java-uitzonderingen (+ antwoorden)

• Vragen over Java-annotaties tijdens sollicitatiegesprekken (+ antwoorden)

• Topvragen tijdens het Spring Framework-interview

1. Inleiding

In dit artikel gaan we in op enkele vragen over geheugenbeheer die vaak opduiken tijdens interviews met Java-ontwikkelaars. Geheugenbeheer is een gebied dat niet zo veel ontwikkelaars kennen.

In feite hoeven ontwikkelaars over het algemeen niet rechtstreeks met dit concept af te rekenen, aangezien de JVM voor de kleinste details zorgt. Tenzij er iets ernstig misgaat, hebben zelfs doorgewinterde ontwikkelaars mogelijk geen nauwkeurige informatie over geheugenbeheer binnen handbereik.

Aan de andere kant komen deze concepten eigenlijk vrij veel voor in interviews - dus laten we meteen beginnen.

2. Vragen

V1. Wat betekent de stelling "Geheugen wordt beheerd in Java"?

Geheugen is de belangrijkste bron die een applicatie nodig heeft om effectief te werken, en net als elke andere bron is het schaars. Als zodanig vereist de toewijzing en deallocatie van en naar applicaties of verschillende delen van een applicatie veel zorg en aandacht.

In Java hoeft een ontwikkelaar echter niet expliciet geheugen toe te wijzen en de toewijzing ervan ongedaan te maken - de JVM en meer specifiek de Garbage Collector - heeft de taak om de geheugentoewijzing af te handelen, zodat de ontwikkelaar dat niet hoeft te doen.

Dit is in tegenstelling tot wat er gebeurt in talen zoals C, waar een programmeur directe toegang heeft tot geheugen en letterlijk verwijst naar geheugencellen in zijn code, waardoor er veel ruimte ontstaat voor geheugenlekken.

Q2. Wat is garbagecollection en wat zijn de voordelen ervan?

Garbage collection is het proces waarbij naar het heap-geheugen wordt gekeken, identificeert welke objecten in gebruik zijn en welke niet, en het verwijderen van de ongebruikte objecten.

Een in gebruik zijnde object, of een object waarnaar wordt verwezen, betekent dat een deel van uw programma nog steeds een verwijzing naar dat object bijhoudt. Naar een ongebruikt object, of object zonder referentie, wordt niet langer verwezen door enig onderdeel van uw programma. Het geheugen dat door een object zonder referentie wordt gebruikt, kan dus worden teruggewonnen.

Het grootste voordeel van garbage collection is dat het de last van handmatige geheugentoewijzing / deallocation van ons wegneemt, zodat we ons kunnen concentreren op het oplossen van het probleem.

Q3. Zijn er nadelen van garbagecollection?

Ja. Elke keer dat de garbage collector wordt uitgevoerd, heeft dit invloed op de prestaties van de applicatie. Dit komt omdat alle andere threads in de applicatie moeten worden gestopt om de garbage collector-thread effectief zijn werk te laten doen.

Afhankelijk van de vereisten van de applicatie, kan dit een reëel probleem zijn dat onaanvaardbaar is voor de klant. Dit probleem kan echter aanzienlijk worden verminderd of zelfs worden geëlimineerd door bekwame optimalisatie en afstemming van garbage collector en het gebruik van verschillende GC-algoritmen.

V4. Wat is de betekenis van de term "Stop-The-World"?

Wanneer de garbage collector-thread actief is, worden andere threads gestopt, wat betekent dat de toepassing tijdelijk wordt gestopt. Dit is analoog aan het schoonmaken of ontsmetten van huizen, waarbij de bewoners de toegang wordt geweigerd totdat het proces is voltooid.

Afhankelijk van de behoeften van een toepassing, kan "stop the world" garbage collection een onaanvaardbare bevriezing veroorzaken. Daarom is het belangrijk om garbage collector-afstemming en JVM-optimalisatie uit te voeren, zodat de ondervonden bevriezing op zijn minst acceptabel is.

V5. Wat zijn stapel en hoop? Wat wordt in elk van deze geheugenstructuren opgeslagen en hoe zijn ze met elkaar verbonden?

De stapel is een deel van het geheugen dat informatie bevat over geneste methodeaanroepen tot aan de huidige positie in het programma. Het bevat ook alle lokale variabelen en verwijzingen naar objecten op de heap die zijn gedefinieerd in momenteel uitgevoerde methoden.

Deze structuur stelt de runtime in staat om terug te keren van de methode, wetend naar het adres waar het werd aangeroepen, en ook alle lokale variabelen te wissen na het verlaten van de methode. Elke thread heeft zijn eigen stapel.

De heap is een groot deel van het geheugen dat bedoeld is voor het toewijzen van objecten. Wanneer u een object maakt met de nieuw trefwoord, wordt het op de hoop toegewezen. De verwijzing naar dit object leeft echter op de stapel.

V6. Wat is generatie-afvalinzameling en wat maakt het tot een populaire aanpak voor afvalinzameling?

Generationele garbage collection kan losjes worden gedefinieerd als de strategie die wordt gebruikt door de garbage collector, waarbij de hoop wordt verdeeld in een aantal secties die generaties worden genoemd, die elk objecten zullen bevatten volgens hun "leeftijd" op de hoop.

Telkens wanneer de garbage collector actief is, wordt de eerste stap in het proces markering genoemd. Hier identificeert de garbage collector welke stukjes geheugen in gebruik zijn en welke niet. Dit kan een zeer tijdrovend proces zijn als alle objecten in een systeem moeten worden gescand.

Naarmate er meer en meer objecten worden toegewezen, wordt de lijst met objecten groter en groter, wat leidt tot een langere en langere garbagecollection-tijd. Empirische analyse van toepassingen heeft echter aangetoond dat de meeste objecten van korte duur zijn.

Met garbagecollection van generaties worden objecten gegroepeerd op basis van hun "leeftijd" in termen van het aantal afvalinzamelingscycli dat ze hebben overleefd. Op deze manier wordt het gros van het werk verspreid over verschillende kleine en grote inzamelcycli.

Tegenwoordig zijn bijna alle vuilnismannen generaties. Deze strategie is zo populair omdat het in de loop van de tijd de optimale oplossing is gebleken.

V7. Beschrijf in detail hoe generatie-afvalinzameling werkt

Om goed te begrijpen hoe generational garbage collection werkt, is het belangrijk om eerst onthoud hoe de Java-heap is gestructureerd om het verzamelen van afval door de generaties te vergemakkelijken.

De hoop is opgedeeld in kleinere ruimtes of generaties. Deze ruimtes zijn Young Generation, Old of Tenured Generation en Permanent Generation.

De jonge generatie herbergt de meeste van de nieuw gemaakte objecten. Een empirische studie van de meeste toepassingen laat zien dat de meeste objecten snel van korte duur zijn en daarom snel in aanmerking komen voor verzameling. Daarom beginnen nieuwe objecten hier hun reis en worden ze pas 'gepromoveerd' naar de oude generatieruimte nadat ze een bepaalde 'leeftijd' hebben bereikt.

De voorwaarde "leeftijd" in generatie garbage collection verwijst naar het aantal verzamelcycli dat het object heeft overleefd.

De ruimte voor jonge generatie is verder onderverdeeld in drie ruimtes: een Eden-ruimte en twee overlevingsruimten zoals Survivor 1 (s1) en Survivor 2 (s2).

De oude generatie host objecten diehebben langer in het geheugen geleefd dan een bepaalde "leeftijd". De objecten die de afvalinzameling van de jonge generatie hebben overleefd, worden naar deze ruimte gepromoot. Het is over het algemeen groter dan de jonge generatie. Omdat het groter is, is de afvalinzameling duurder en komt het minder vaak voor dan bij de jonge generatie.

De permanente generatieof vaker genoemd, PermGen, bevat metadata vereist door de JVM om de klassen en methoden te beschrijven die in de applicatie worden gebruikt. Het bevat ook de stringpool voor het opslaan van geïnterneerde strings. Het wordt tijdens runtime door de JVM gevuld op basis van klassen die door de toepassing worden gebruikt. Bovendien kunnen hier klassen en methoden van platformbibliotheken worden opgeslagen.

Eerste, alle nieuwe objecten worden toegewezen aan de Eden-ruimte. Beide overlevingsruimten beginnen leeg. Wanneer de Eden-ruimte vol raakt, wordt een kleine garbagecollection geactiveerd. Objecten waarnaar wordt verwezen, worden verplaatst naar de eerste overlevingsruimte. Objecten zonder verwijzing worden verwijderd.

Tijdens de volgende kleine GC gebeurt hetzelfde met de Eden-ruimte. Objecten zonder verwijzing worden verwijderd en objecten waarnaar wordt verwezen, worden verplaatst naar een overlevingsruimte. In dit geval worden ze echter verplaatst naar het tweede overlevingsvak (S2).

Bovendien wordt de leeftijd van objecten uit de laatste kleine GC in de eerste overlevingsruimte (S1) verhoogd en verplaatst naar S2. Zodra alle overgebleven objecten naar S2 zijn verplaatst, worden zowel S1 als Eden-ruimte vrijgemaakt. Op dit punt bevat S2 objecten met verschillende leeftijden.

Bij de volgende kleine GC wordt hetzelfde proces herhaald. Maar deze keer wisselen de overlevingsruimten. Objecten waarnaar wordt verwezen, worden vanuit Eden en S2 naar S1 verplaatst. Overlevende objecten zijn verouderd. Eden en S2 zijn gewist.

Na elke kleine afvalinzamelingscyclus wordt de ouderdom van elk object gecontroleerd. Degenen die een bepaalde willekeurige leeftijd hebben bereikt, bijvoorbeeld 8, worden gepromoveerd van de jonge generatie naar de oude of vaste generatie. Voor alle volgende kleine GC-cycli worden objecten verder gepromoveerd naar de oude generatieruimte.

Dit put het proces van afvalinzameling in de jonge generatie vrijwel uit. Uiteindelijk zal er een grote garbage collection worden uitgevoerd op de oude generatie die die ruimte opruimt en comprimeert. Voor elke grote GC zijn er verschillende kleine GC's.

V8. Wanneer komt een object in aanmerking voor garbagecollection? Beschrijf hoe de GC een in aanmerking komend object verzamelt?

Een object komt in aanmerking voor Garbage collection of GC als het niet bereikbaar is vanuit live threads of door statische verwijzingen.

Het meest eenvoudige geval waarin een object in aanmerking komt voor garbagecollection, is als alle verwijzingen nul zijn. Cyclische afhankelijkheden zonder enige live externe referentie komen ook in aanmerking voor GC. Dus als object A verwijst naar object B en object B verwijst naar object A en ze geen andere live-referentie hebben, komen zowel objecten A als objecten B in aanmerking voor garbagecollection.

Een ander voor de hand liggend geval is wanneer een bovenliggend object is ingesteld op null. Wanneer een keukenobject intern verwijst naar een koelkastobject en een gootsteenobject, en het keukenobject is ingesteld op nul, komen zowel de koelkast als de gootsteen in aanmerking voor afvalinzameling naast hun ouder, de keuken.

V9. Hoe activeer je garbagecollection vanuit Java-code?

Jij, als Java-programmeur, kunt garbage collection in Java niet afdwingen; het wordt alleen geactiveerd als JVM denkt dat het een garbagecollection nodig heeft op basis van de Java-heapgrootte.

Voordat een object uit het geheugen wordt verwijderd, roept de garbagecollection-thread de methode finalize () van dat object op en geeft deze de mogelijkheid om elke gewenste opschoning uit te voeren. U kunt deze methode van een objectcode ook aanroepen, maar er is geen garantie dat garbage collection zal plaatsvinden wanneer u deze methode aanroept.

Bovendien zijn er methoden zoals System.gc () en Runtime.gc () die worden gebruikt om het verzoek van Garbage collection naar JVM te sturen, maar het is niet gegarandeerd dat garbage collection zal plaatsvinden.

V10. Wat gebeurt er als er niet genoeg opslagruimte is om nieuwe objecten op te slaan?

Als er geen geheugenruimte is voor het maken van een nieuw object in Heap, gooit Java Virtual Machine Onvoldoende geheugen fout of meer specifiekjava.lang.OutOfMemoryError hoop ruimte.

V11. Is het mogelijk om een ​​object dat in aanmerking kwam voor afvalinzameling te "doen herleven"?

Wanneer een object in aanmerking komt voor garbage collection, moet de GC de afronden methode erop. De afronden De methode wordt gegarandeerd slechts één keer uitgevoerd, dus de GC markeert het object als voltooid en geeft het een rustpauze tot de volgende cyclus.

In de afronden methode kun je een object technisch 'herleven', bijvoorbeeld door het toe te wijzen aan een statisch veld. Het object zou weer tot leven komen en niet in aanmerking komen voor garbage collection, dus de GC zou het tijdens de volgende cyclus niet ophalen.

Het object zou echter als voltooid worden gemarkeerd, dus als het weer in aanmerking komt, wordt de methode voor het voltooien niet aangeroepen. In wezen kun je deze "wederopstanding" -truc maar één keer gebruiken voor de levensduur van het object. Pas op dat deze lelijke hack alleen moet worden gebruikt als u echt weet wat u doet, maar als u deze truc begrijpt, krijgt u enig inzicht in hoe de GC werkt.

V12. Beschrijf sterke, zwakke, zachte en fantoomreferenties en hun rol bij de afvalinzameling.

Net zoals geheugen wordt beheerd in Java, moet een ingenieur mogelijk zoveel mogelijk optimalisatie uitvoeren om de latentie te minimaliseren en de doorvoer te maximaliseren in kritieke toepassingen. Veel als het is onmogelijk om expliciet te bepalen wanneer garbage collection wordt geactiveerd in de JVM, het is mogelijk om te beïnvloeden hoe het gebeurt met betrekking tot de objecten die we hebben gemaakt.

Java biedt ons referentieobjecten om de relatie tussen de objecten die we maken en de garbage collector te controleren.

Standaard wordt naar elk object dat we in een Java-programma maken sterk verwezen door een variabele:

StringBuilder sb = nieuwe StringBuilder ();

In het bovenstaande fragment, de nieuw trefwoord maakt een nieuw StringBuilder object en slaat het op de hoop op. De variabele sb slaat vervolgens een sterke referentie naar dit object. Wat dit betekent voor de vuilnisman is dat het bijzondere StringBuilder object komt in het geheel niet in aanmerking voor verzameling vanwege een sterke verwijzing ernaar door sb. Het verhaal verandert pas als we opheffen sb soortgelijk:

sb = null;

Na het aanroepen van bovenstaande regel komt het object dan voor afhaling in aanmerking.

We kunnen deze relatie tussen het object en de garbage collector veranderen door het expliciet in een ander referentieobject te wikkelen dat zich binnenin bevindt java.lang.ref pakket.

EEN zachte referentie kan als volgt aan het bovenstaande object worden gemaakt:

StringBuilder sb = nieuwe StringBuilder (); SoftReference sbRef = nieuwe SoftReference (sb); sb = null;

In het bovenstaande fragment hebben we twee verwijzingen gemaakt naar het StringBuilder voorwerp. De eerste regel maakt een sterke referentiesb en de tweede regel maakt een zachte referentiesbRef. De derde regel moet ervoor zorgen dat het object in aanmerking komt voor verzameling, maar de garbage collector zal het ophalen uitstellen vanwege sbRef.

Het verhaal zal alleen veranderen als het geheugen krap wordt en de JVM op het punt staat een OutOfMemory fout. Met andere woorden, objecten met alleen zachte referenties worden verzameld als laatste redmiddel om geheugen te herstellen.

EEN zwakke referentie kan op een vergelijkbare manier worden gemaakt met Zwakke referentie klasse. Wanneer sb is ingesteld op null en de StringBuilder object heeft slechts een zwakke referentie, de garbage collector van de JVM zal absoluut geen compromissen sluiten en het object onmiddellijk ophalen bij de volgende cyclus.

EEN fantoomreferentie is vergelijkbaar met een zwakke referentie en een object met alleen fantoomreferenties wordt verzameld zonder te wachten. Fantoomreferenties worden echter in de wachtrij geplaatst zodra hun objecten zijn verzameld. We kunnen de referentiewachtrij opvragen om precies te weten wanneer het object is opgehaald.

V13. Stel dat we een circulaire referentie hebben (twee objecten die naar elkaar verwijzen). Zou een dergelijk paar objecten in aanmerking kunnen komen voor afvalinzameling en waarom?

Ja, een paar objecten met een kringverwijzing kunnen in aanmerking komen voor garbage collection. Dit komt door de manier waarop Java's garbage collector omgaat met kringverwijzingen. Het beschouwt objecten niet als live als ze ernaar verwijzen, maar als ze bereikbaar zijn door door de objectgrafiek te navigeren, beginnend bij een garbage collection-root (een lokale variabele van een live thread of een statisch veld). Als een paar objecten met een kringverwijzing vanuit geen enkele root bereikbaar is, komt het in aanmerking voor garbage collection.

V14. Hoe worden tekenreeksen in het geheugen weergegeven?

EEN Draad instantie in Java is een object met twee velden: a char [] waarde veld en een int hash veld. De waarde veld is een reeks tekens die de tekenreeks zelf vertegenwoordigen, en de hash veld bevat de hashCode van een string die is geïnitialiseerd met nul, berekend tijdens de eerste hashCode () bellen en sindsdien in de cache opgeslagen. Als een merkwaardig geval, als een hashCode van een string een nulwaarde heeft, moet deze elke keer dat de hashCode () wordt genoemd.

Belangrijk is dat a Draad instantie is onveranderlijk: u kunt de onderliggende waarde niet krijgen of wijzigen char [] array. Een ander kenmerk van strings is dat de statische constante strings worden geladen en in de cache worden opgeslagen in een stringpool. Als u meerdere identieke Draad objecten in uw broncode, worden ze tijdens runtime allemaal vertegenwoordigd door één instantie.

V15. Wat is een stringbuilder en wat zijn de use cases? Wat is het verschil tussen het toevoegen van een string aan een stringbuilder en het aaneenschakelen van twee strings met een + operator? Hoe verschilt Stringbuilder van Stringbuffer?

StringBuilder maakt het manipuleren van tekenreeksen mogelijk door het toevoegen, verwijderen en invoegen van tekens en tekenreeksen. Dit is een veranderlijke gegevensstructuur, in tegenstelling tot de Draad klasse die onveranderlijk is.

Bij het aaneenschakelen van twee Draad exemplaren wordt een nieuw object gemaakt en worden strings gekopieerd. Dit kan een enorme garbage collector overhead opleveren als we een string in een lus moeten maken of wijzigen. StringBuilder maakt het mogelijk om stringmanipulaties veel efficiënter af te handelen.

StringBuffer verschilt van StringBuilder omdat het draadveilig is. Als u een string in een enkele thread wilt manipuleren, gebruikt u StringBuilder in plaats daarvan.

3. Conclusie

In dit artikel hebben we enkele van de meest voorkomende vragen behandeld die vaak voorkomen in interviews met Java-ingenieurs. Vragen over geheugenbeheer worden meestal gesteld aan kandidaten voor Senior Java Developer, aangezien de interviewer verwacht dat je niet-triviale applicaties hebt gebouwd die vaak worden geplaagd door geheugenproblemen.

Dit moet niet worden beschouwd als een uitputtende lijst met vragen, maar eerder als een lanceerplatform voor verder onderzoek. Wij, bij Baeldung, wensen u veel succes bij de komende interviews.

De volgende » Java Generics sollicitatievragen (+ antwoorden) « Vorige Java 8 sollicitatievragen (+ antwoorden)