9 svar
65 visningar
sampledragon5 är nöjd med hjälpen
sampledragon5 495
Postad: 16 jan 10:33

Stack, heap, recursion.

public class Person {
Person p2 = new Person();

public Person() {
  System.out.println("hello world");
}


public static void main(String[] args) {
  Person p1 = new Person();
}

}

 

Hej! 

Jag fattar inte logiken till varför koden resulterar i stackOverFlow men inte OutOfMemoryError. När main metoden körs så hamnar den i stacken tillsammans med referensvariablen p1. Sedan så skapas ett person objekt (the new keyword skapar objekt), vilket kommer leda till att p1 kommer att referera till detta nyskapta objekt MEN sedan har vi en instansvariabel, p2, som i sin tur refererar till ett person object... så, det jag menar är att först så kommer ett person objekt att skapas, sedan ett till, och ett till, och ett till.... en konstuktor skapar inte objekt, en konstruktor initiera objekt... så frågan är, när körs konstroktorn för programmet har ju hamnat i en loop ( en loop som skapar massor av person objekt i heap?) 🤔 

Laguna Online 28602
Postad: 16 jan 10:46

Det kan vara så att stacken tar slut innan minnet gör det.

D4NIEL Online 2546
Postad: 16 jan 11:20

När du anropar en funktion pushas anropande funktions adress på stacken.

När den anropade funktionen är klar poppas returadressen från stacken till instruktionspekaren.

När du går in i en rekursiv loop fylls stacken snabbt av anropande adresser. Beroende på implementation, språk osv kan det räcka med några hundra till några tusen anrop för att krascha.

sampledragon5 495
Postad: 16 jan 11:48
Laguna skrev:

Det kan vara så att stacken tar slut innan minnet gör det.

Sant, fast hur hamnar konstroktorn på stacken ens ? jag menar på att massor med person objekt skapas ( vilket the new keyword skapar, inte en konstruktor) Jag menar alltså på att det endast borde vara main metoden och p1 som är i stacken ( men uppenbarligen är massor med konstruktor i stacken (vilket har resulterat i stackOverFlow) men jag förstår inte logiken till att de har hamnat där... 😕

sampledragon5 495
Postad: 16 jan 11:48
D4NIEL skrev:

När du anropar en funktion pushas anropande funktions adress på stacken.

När den anropade funktionen är klar poppas returadressen från stacken till instruktionspekaren.

När du går in i en rekursiv loop fylls stacken snabbt av anropande adresser. Beroende på implementation, språk osv kan det räcka med några hundra till några tusen anrop för att krascha.

Sant, fast hur hamnar konstroktorn på stacken ens ? jag menar på att massor med person objekt skapas ( vilket the new keyword skapar, inte en konstruktor) Jag menar alltså på att det endast borde vara main metoden och p1 som är i stacken ( men uppenbarligen är massor med konstruktor i stacken (vilket har resulterat i stackOverFlow) men jag förstår inte logiken till att de har hamnat där... 😕

Laguna Online 28602
Postad: 16 jan 15:30

När man skapar en Person så körs ju det här: Person p2 = new Person();

Då skapas en ny Person, och då körs det här: Person p2 = new Person();

...

sampledragon5 495
Postad: 17 jan 11:55
Laguna skrev:

När man skapar en Person så körs ju det här: Person p2 = new Person();

Då skapas en ny Person, och då körs det här: Person p2 = new Person();

...

Jo jag vet men grejen är ju såhär att när en person objekt har skapats så hamnar den i heap, inte stacken. Dock är jag medveten om att när en konstruktor körs så hamnar konstroktorn i stacken MEN det jag inte får ihop i huvudet är att först så skapas ett objekt MEN sedan, när objektet har skapats, så körs konstroktorn (för att initiera det nyskapata objektet)  MEN problemet är ju att programmet redan har hamnat i en loop (den skapar ju massor av objekt i heap) så när lyckas programmet köra konstroktorn ? Det verkar som att konstroktorn inte ens körs eftersom när jag körde programmet så printas inte "hello word" på min konsol överhuvudtaget... samt när jag debugged koden med en debugger (jag använder intelij) så kördes inte koden som finns inuti konstroktorns kropp.... så, om inte det är massor av konstruktor som resulterar i stackOverFlow.... vad är det så som tar all minne från stacken 🤔

Laguna Online 28602
Postad: 17 jan 13:21

Det där ovanstående är på stacken: skaparfunktionen anropar sig själv.

sampledragon5 495
Postad: 17 jan 13:45
Laguna skrev:

Det där ovanstående är på stacken: skaparfunktionen anropar sig själv.

Kan du snälla utveckla vad du menar 🤔

Laguna Online 28602
Postad: 17 jan 17:27

Det man har stacken till är att spara information om var programmet kör, för att man ska kunna komma tillbaka dit efter ett anrop av en funktion (eller metod eller konstruktor).

När man anropar en funktion f1 så hoppar man dit och börjar exekvera dess kod. När f1 är klar så ska man fortsätta köra där man var före anropet. Hur hittar man dit? Den returpunkten måste sparas någonstans under tiden, och det är på stacken man sparar den.

Om en funktion anropar sig själv, så kommer varje nytt anrop att lägga en returpunkt på stacken. Innan man är klar och hoppar tillbaka ska man i det här fallet göra ett nytt anrop till sig själv. Stacken bara växer och tar till sist slut.

Att anropa sig själv behöver inte vara fel, men man måste någon gång returnera i stället för att först göra fler anrop. Det gör man inte här. Person-konstruktorn skapar först attributet p2 och för att göra det behöver den först anropa Person-konstruktorn för att skapa en ny instans. Först när p2 är skapad körs din kod i konstruktorn.

Du kan göra experimentet att skriva bara Person p2; i början och sedan göra p2 = new Person(); i konstruktorn, före utskriften.

Svara Avbryt
Close