Springen naar inhoud

java, geheugen vol met iterators


  • Log in om te kunnen reageren

#1

Math-E-Mad-X

    Math-E-Mad-X


  • >1k berichten
  • 2382 berichten
  • Ervaren gebruiker

Geplaatst op 10 januari 2014 - 17:51

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:
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(); }

Dit forum kan gratis blijven vanwege banners als deze. Door te registeren zal de onderstaande banner overigens verdwijnen.

#2

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 13 januari 2014 - 08:06

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?

#3

Math-E-Mad-X

    Math-E-Mad-X


  • >1k berichten
  • 2382 berichten
  • Ervaren gebruiker

Geplaatst op 13 januari 2014 - 11:02

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(); }

#4

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 15 januari 2014 - 09:34

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?

#5

Math-E-Mad-X

    Math-E-Mad-X


  • >1k berichten
  • 2382 berichten
  • Ervaren gebruiker

Geplaatst op 15 januari 2014 - 12:04

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?

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.

//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 :)

Veranderd door Math-E-Mad-X, 15 januari 2014 - 12:04

while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }

#6

Flisk

    Flisk


  • >1k berichten
  • 1270 berichten
  • Moderator

Geplaatst op 15 januari 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.

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.
Je leest maar niet verder want je, je voelt het begin van wanhoop.

#7

Math-E-Mad-X

    Math-E-Mad-X


  • >1k berichten
  • 2382 berichten
  • Ervaren gebruiker

Geplaatst op 16 januari 2014 - 11:46

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(); }

#8

rwwh

    rwwh


  • >5k berichten
  • 6847 berichten
  • Moderator

Geplaatst op 29 januari 2014 - 08:20

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.

#9

Math-E-Mad-X

    Math-E-Mad-X


  • >1k berichten
  • 2382 berichten
  • Ervaren gebruiker

Geplaatst op 03 februari 2014 - 17:52

bedankt voor de tip :)
while(true){ Thread.sleep(60*1000/180); bang_bassdrum(); }

#10

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 04 februari 2014 - 08:21

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.





0 gebruiker(s) lezen dit onderwerp

0 leden, 0 bezoekers, 0 anonieme gebruikers

Ook adverteren op onze website? Lees hier meer!

Gesponsorde vacatures

Vacatures