CodeGym /Java blogg /Slumpmässig /Objektets livscykel
John Squirrels
Nivå
San Francisco

Objektets livscykel

Publicerad i gruppen
Hej! Jag tror att du inte skulle bli särskilt förvånad om jag berättade att din dator har en begränsad mängd minne :)
Objektets livscykel - 1
Till och med din hårddisk (som är många, många gånger så stor som RAM) kan bli fullproppad med dina favoritspel, TV-program och andra saker. För att förhindra att detta händer måste du övervaka det aktuella tillståndet i din dators minne och radera onödiga filer. Hur hänger allt detta ihop med Java-programmering? Ganska direkt! När allt kommer omkring gör att skapa ett objekt gör att Java-maskinen allokerar minne för det . Ett stort verkligt program skapar tiotals eller hundratusentals objekt, och en bit minne tilldelas för vart och ett av dem. Men vad tror du, hur många av dessa föremål finns det? Är de "levande" hela tiden vårt program körs? Självklart inte. Även med alla sina fördelar är Java-objekt inte odödliga :) Objekt har sin egen livscykel. Idag tar vi en liten paus från att skriva kod och utforskar denna process :) Det är också mycket viktigt för att förstå hur ett program fungerar och för att hantera resurser. Så, var börjar ett objekts liv? Som en människa, från födseln, alltså när den skapas.

Cat cat = new Cat();// Our Cat object's lifecycle begins now!
Först allokerar den virtuella Java-maskinen det minne som krävs för att skapa objektet. Sedan skapar den en referens till den (i vårt fall, cat) för att göra det möjligt att hålla reda på det. Sedan initieras alla variabler, konstruktorn anropas och vårt nya objekt lever nu sitt eget liv :) Objektets livslängder varierar. Det finns inga exakta siffror här. I alla händelser lever ett objekt i programmet och utför sina funktioner under en viss tidsperiod. För att vara exakt så är föremålet "levande" så länge det finns referenser till det. Så fort det inte finns några referenser "dör objektet". Till exempel:

public class Car {
  
   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");
       lamborghini = null;

   }

}
I main()metoden upphör objektet "Lamborghini Diablo" Car att vara vid liv på andra raden. Det fanns bara en referens till den, och referensen var inställd på null. Eftersom det inte finns några kvarvarande referenser till Diablo blir det "skräp". En referens behöver inte vara noll för att detta ska hända:

public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");

       Car lamborghiniGallardo = new Car("Lamborghini Gallardo");
       lamborghini = lamborghiniGallardo;
   }

}
Här har vi skapat ett andra objekt och tilldelat det till lamborghini-referensen. Nu pekar två referenser till Lamborghini Gallardoobjektet, men Lamborghini Diabloobjektet har ingen. Detta innebär att Diabloföremålet blir skräp. Det är då Javas inbyggda garbage collector (GC) slår in.
Objektets livscykel - 2
Skräpsamlaren är en intern Java-mekanism som ansvarar för att frigöra minne, det vill säga att ta bort onödiga föremål från minnet. Det finns en anledning till att vi valde att representera det med en robotdammsugare. Sophämtaren fungerar på ungefär samma sätt: den "rör sig" i ditt program i bakgrunden och samlar skräp. Du behöver praktiskt taget inte interagera med den. Dess uppgift är att ta bort objekt som inte längre används i programmet. Således frigör det minne för andra objekt. Kommer du ihåg att du i början av lektionen sa i verkligheten måste övervaka din dators tillstånd och radera gamla filer? Om vi ​​pratar om Java-objekt, gör sopsamlaren detta åt dig. Skräpsamlaren startas många gånger när ditt program körs: du behöver inte uttryckligen kalla det och ge det kommandon (även om detta är tekniskt möjligt). Vi kommer att prata mer om sophämtaren senare och analysera hur den fungerar mer i detalj. När sopsamlaren når ett föremål – precis innan det förstörs – finalize()kallas föremålets speciella metod. Denna metod kan anropas för att frigöra vissa ytterligare resurser som används av objektet. Metoden finalize()tillhör klassen Object. Med andra ord, det liknar equals(), hashCode()och toString()(som du tidigare har träffat). Varje föremål har det . Det skiljer sig från andra metoder genom att...hur ska vi säga detta...det är väldigt medvetet. Med det menar vi detdet anropas inte alltid innan ett föremål förstörs . Programmering är en mycket exakt aktivitet. Programmeraren säger åt datorn att göra något, och datorn gör det. finalize()Jag antar att du har blivit van vid den här typen av beteende, så till en början kan det vara svårt för dig att acceptera följande idé: "Innan ett objekt förstörs , kallas Object-klassens metod. Eller inte. Om vi ​​har tur! " Ändå är detta verkligheten. Java-maskinen avgör själv om finalize() ska anropas från fall till fall. Som ett experiment, låt oss försöka köra följande kod:

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public Cat() {
   }

   public static void main(String[] args) throws Throwable {

       for (int i = 0 ; i < 1000000; i++) {

           Cat cat = new Cat();
           cat = null;// The first object becomes available for garbage collection here
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("The Cat is destroyed!");
   }
}
Vi skapar ett Catobjekt och på nästa rad nollställer vi den enda referensen till det. Och det gör vi en miljon gånger. Vi har uttryckligen åsidosatt finalize()metoden. Varje gång ett Catobjekt förstörs måste det visa en sträng – totalt en miljon gånger. Men nej! För att vara exakt, på min dator kördes det bara 37346 gånger! Med andra ord, min Java-maskin bestämde sig för att anropa finalize()metoden i endast 1 av 27 fall. I de andra fallen omfattade inte sophämtning detta samtal. Testa att köra den här koden själv. Du kommer med största sannolikhet att få ett annat resultat. Som du kan se är det svårt att kalla finalize()en pålitlig partner :) Så här är ett litet tips för framtiden: lita inte på metoden finalize()för att frigöra kritiska resurser.JVM kan kalla det, eller så kanske det inte. Vem vet? Om ditt objekt hade några prestandakritiska resurser (till exempel en öppen databasanslutning) medan det levde, skulle det vara bättre att skapa och uttryckligen anropa en speciell metod för att frigöra dem när objektet inte längre behövs. På så sätt vet du säkert att ditt programs prestanda inte blir lidande. Vi började med att säga att arbetet med minne och sophämtning är väldigt viktiga ämnen, och det är de verkligen. Felhantering av resurser och missförstånd av hur onödiga föremål rensas upp kan leda till en av de mest obehagliga buggarna: minnesläckor . Detta är ett av de mest kända programmeringsfelen. Den har till och med en egen Wikipedia- artikel. Dåligt skriven kod kan skapa en situation där minne tilldelas varje gång för nyskapade objekt, men gamla, onödiga objekt är otillgängliga för sophämtning. Eftersom vi redan har gjort en robotdammsugaranalogi, föreställ dig vad som skulle hända om du innan du körde roboten spred strumpor över hela huset, krossade en glasvas och lämnade legobitar över hela golvet. Naturligtvis skulle roboten försöka göra något, men en dag kommer den att gripa tag.
Objektets livscykel - 3
För att dammsugaren ska fungera som den ska måste du hålla golvet i hyfsad form och plocka upp allt som den inte klarar av. Sopsamlaren följer samma princip. Om ett program har många föremål som det inte kan städa upp (som en strumpa eller lego till vår robotdammsugare), kommer vi en dag att få slut på minne. Inte bara kommer ditt program att hänga sig, alla andra program som råkar köras på datorn kommer också att göra det. När allt kommer omkring kommer de inte att ha tillräckligt med minne heller (om vi återgår till vår analogi, det krossade glaset på golvet stoppar inte bara dammsugaren, utan också människorna som bor i hemmet). Kort sagt, så här ser objekts livscykel och sophämtning ut i Java. Du behöver inte memorera detta: det räcker att bara förstå hur det fungerar. I nästa lektion, vi återkommer till dessa processer mer i detalj. Men för nu kan du återgå till att lösa CodeGym-uppgifter :) Lycka till!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION