Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

java, geheugen vol met iterators

Bij het profilen van mijn applicatie kom ik er achter dat het grootste gedeelte van het geheugen in beslag wordt genomen door objecten van het type ArrayList$Itr

Ik heb inderdaad een heleboel loops over ArrayLists in mijn code, maar ik heb geen idee hoe ik kan dit probleem zou kunnen voorkomen.

Is er een manier om er voor te zorgen dat de iterators sneller opgeruimd worden?

Of kun je ze hergebruiken zodat je niet steeds een nieuwe hoeft aan te maken bij iedere nieuwe loop?

Op StackOverflow vond ik als tip om gewoon te itereren op de 'klassieke' manier:

Code: Selecteer alles


for(int i=0; i<myList.size(); i++){

   etc...

}

Nu kan ik dit wel gaan proberen natuurlijk, maar het is behoorlijk veel werk om dat overal in mijn code te gaan doen, dus het leek me handiger om hier eens te vragen wat jullie mening hierover is.
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
EvilBro
Artikelen: 0
Berichten: 7.081
Lid geworden op: vr 30 dec 2005, 09:45

Re: java, geheugen vol met iterators

Ik heb inderdaad een heleboel loops over ArrayLists in mijn code, maar ik heb geen idee hoe ik kan dit probleem zou kunnen voorkomen.
Is het ook daadwerkelijk een probleem?
Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Re: java, geheugen vol met iterators

Het gaat om tientallen Megabytes, en soms zelfs honderden. Voorlopig trekt mijn computer het nog wel, maar ik ben bang dat dit wel een probleem gaat worden als ik het programma uitbreidt of als ik meerdere instanties van het programma naast elkaar wil draaien.

En ook als het nooit tot problemen zal leiden, dan nog is het natuurlijk gewoon interessant om te weten hoe ik dit zou kunnen oplossen :P
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
EvilBro
Artikelen: 0
Berichten: 7.081
Lid geworden op: vr 30 dec 2005, 09:45

Re: java, geheugen vol met iterators

Het gaat om tientallen Megabytes, en soms zelfs honderden.
Als je die Megabytes verder niet nodig hebt dan is er voor de garbage collector ook geen reden om die ruimte op te ruimen. Als die ruimte uberhaupt opgeruimd kan worden natuurlijk: Ik neem aan dat je algoritme wel al klaar is met de iterators. Heb je een SSCCE?
Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Re: java, geheugen vol met iterators

EvilBro schreef: wo 15 jan 2014, 09:34
Als je die Megabytes verder niet nodig hebt dan is er voor de garbage collector ook geen reden om die ruimte op te ruimen.
Ja, das waar, maar op een gegeven moment zal ik die ruimte wel nodig gaan hebben en ben bang dat de garbage collector dan veel tijd nodig zal hebben om al die troep op te ruimen. Vandaar dat het me handiger leek om in plaats daarvan gewoon te voorkomen dat het geheugen vol raakt. En als ik niet kan voorkomen dat het geheugen vol raakt dan lijkt het me nog altijd beter om in elk geval te zorgen dat het zolang mogelijk duurt voordat het geheugen vol raakt.

Of zou het tijdsverlies verwaarloosbaar zijn?
EvilBro schreef: wo 15 jan 2014, 09:34
Ik neem aan dat je algoritme wel al klaar is met de iterators. Heb je een SSCCE?
Ja, ik doe niks meer dan gewoon een foreach loop maken, zonder expliciet een iterator aan te maken. De iterator zal dus direct uit scope raken zodra de loop klaar is.

Code: Selecteer alles


//deze foreach loop maakt impliciet een iterator aan:

for(Object x : myListOfObjects){

   //blablabla

}

//hier is de iterator uit scope en kan dus opgeruimd worden.

Veel shorter en self-containender kan ik het niet maken :)
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
Gebruikersavatar
Flisk
Artikelen: 0
Berichten: 1.264
Lid geworden op: vr 02 mar 2012, 14:21

Re: java, geheugen vol met iterators

Ikzelf gebruik bijna nooit een iterator, behalve als het echt nodig is.

Zover ik weet maakt het niet uit welke van de twee je gebruikt qua performance. Ik denk dat het gewoon 'syntactic sugar' is.

For each is gewoonweg beter leesbaar. Tenzij je objecten moet verwijderen uit de lijst, zou ik geen iterator gebruiken.

Een goeie site voor dit soort vragen is stackoverflow:

http://stackoverflow.com/questions/1879255/traditional-for-loop-vs-iterator-in-java

Deze vraag toont zelfs aan dat het verschil verwaarloosbaar is (zie de post van sfussenegger). In sommige gevallen is een iterator zelf sneller. Qua geheugen weet ik het niet 100% zeker.
Je leest maar niet verder want je, je voelt het begin van wanhoop.
Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Re: java, geheugen vol met iterators

Flisk schreef: wo 15 jan 2014, 22:43
Ikzelf gebruik bijna nooit een iterator, behalve als het echt nodig is.

Zover ik weet maakt het niet uit welke van de twee je gebruikt qua performance. Ik denk dat het gewoon 'syntactic sugar' is.

For each is gewoonweg beter leesbaar. Tenzij je objecten moet verwijderen uit de lijst, zou ik geen iterator gebruiken.
Bedankt voor je antwoord. Even voor de duidelijkheid: het ging mij om het verschil tussen een 'traditional' for loop en een foreach loop. Het eerste en het derde voorbeeld uit die link van je dus.

De loop met expliciete iterator gebruik ik zelf inderdaad ook nooit.

Een goeie site voor dit soort vragen is stackoverflow:

http://stackoverflow...terator-in-java

Deze vraag toont zelfs aan dat het verschil verwaarloosbaar is (zie de post van sfussenegger). In sommige gevallen is een iterator zelf sneller. Qua geheugen weet ik het niet 100% zeker.
Dat topic had ik zelf inmiddels ook gevonden ja. Goed om te weten dat het vrijwel niet uitmaakt. :)
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
Gebruikersavatar
rwwh
Artikelen: 0
Berichten: 6.853
Lid geworden op: wo 02 mar 2005, 22:23

Re: java, geheugen vol met iterators

Even een zijlijn van iemand die zelf niet in Java programmeert: als je wilt voorkomen dat je garbage collector heel lang draait als hij eenmaal gaat lopen, kun je de totale hoeveelheid beschikbaar geheugen reduceren. Als er minder vrij geheugen is, zal gc vaker gaan lopen en minder variatie veroorzaken in de run-time. Natuurlijk neem je daarbij aan dat je het geheugen niet elders voor andere zaken nodig hebt.
Gebruikersavatar
Math-E-Mad-X
Artikelen: 0
Berichten: 2.907
Lid geworden op: wo 13 sep 2006, 17:31

Re: java, geheugen vol met iterators

bedankt voor de tip :)
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }
EvilBro
Artikelen: 0
Berichten: 7.081
Lid geworden op: vr 30 dec 2005, 09:45

Re: java, geheugen vol met iterators

als je wilt voorkomen dat je garbage collector heel lang draait als hij eenmaal gaat lopen, kun je de totale hoeveelheid beschikbaar geheugen reduceren.
Dit is misschien (en ook dan slechts misschien) handig als je een applicatie hebt die tijdgerelateerde doelen heeft. In alle andere gevallen wil je zo min mogelijk de garbage collector aanroepen om de overhead hiervan te beperken.

Mijn inziens is je bezighouden met de garbage collector sowieso al fout. Dat ding is er zodat jij je niet met het geheugen hoeft bezig te houden; Alleen als blijkt dat je je ermee moet bemoeien, slechts dan ga je dat doen.

Terug naar “Informatica en programmeren”