I computerens første mange år var det en helt nødvendig færdighed for programmører at holde styr på præcist, hvor meget af hukommelsen der blev brugt og til hvad. Men moderne styresystemer og programmeringssprog gør det næsten altid muligt aldrig at skænke hukommelsen en tanke.
Forbløffende få gennemgår øvelsen med at finde ud af, hvor meget hukommelse deres program vil bruge
Der er imidlertid grund til at tænke over hukommelsesforbruget, hvis man enten arbejder med software til meget små enheder som eksempelvis de mindste udgaver af Raspberry Pi eller endnu mindre computere til Internet of Things.
Men også i store enterprise-systemer kan hukommelsesforbruget påvirke ydelsen.
»Det er forbløffende få, der gennemgår øvelsen med at finde ud af, hvor meget hukommelse deres program vil bruge, fordi hukommelse er billigt. Men det er ikke nødvendigvis tilfældet på små enheder som Raspberry Pi,« forklarede Kees Jan Koster, stifter af Java Monitor, på Java-konferencen JDK.IO.
Hukommelse bliver for eksempel brugt, hver eneste gang man i objektorienteret programmering opretter et nyt objekt. Det bruger en lille bid af hukommelsen, som bliver reserveret til objektet.
Ældre sprog kræver manuel ophævelse
De fleste ældre programmeringssprog forudsætter, at programmøren manuelt sørger for at frigive det reserverede område, når objektet ikke længere skal bruges, men i dag bruger flere sprog garbage collection.
Garbage collection blev ganske vist allerede introduceret i Lisp i 1959, men i forhold til at skrive oprydningen ind i selve programmet, så blev garbage collection anset for at være for dyrt i processorcyklusser. Da Java blev introduceret i 1995, valgte man at bygge garbage collection ind i den virtuelle maskine, Java-applikationer blev udviklet på.
Den type garbage collection, Java benytter, kaldes generational. Det dækker over, at hukommelsen kategoriseres efter, om et område for eksempel er helt uberørt af allokerede objekter, eller om det indeholder nogle objekter, der stadig er i brug, men området har været gennem en oprydning.
Udfordringen for garbage collection er, at det ikke er gratis. Den skal finde ud af, om der stadig er noget, der bruger en del af hukommelsen, og når der er blevet ryddet op mange gange, så kan det blive nødvendigt at flytte rundt på allokationer, fordi den ledige plads mellem dem så at sige er for trang.
Faktisk indeholder Java-platformen en kombination af forskellige garbage collection-metoder, og hvis man som udvikler arbejder med systemer, hvor garbage collection kan blive et problem, så er det muligt at justere på en række parametre.
Garbage collection kræver programstop
Et af problemer er, at garbage collection er nødt til at stoppe programmet kortvarigt, mens der ryddes op. Hvis det ikke håndteres på den rigtige måde, så kan man få et program, hvor disse pauser er mærkbare. Det kan eksempelvis være spil eller andre hukommelseskrævende programmer, hvor brugeren kan bemærke de små pauser.
Som udvikler kan man også have garbage collection i tankerne, når man skriver sin kode, og ikke blot efterfølgende når ydelsen skal finjusteres.
»Du skal ikke være bange for at generere en masse objekter, hvis du lader dem dø hurtigt. Det er billig garbage collection. Alternativt skal du lade dem leve virkelig længe,« forklarer Kees Jan Koster.
Garbage collection kan også få problemer med meget store allokeringer. Det kan eksempelvis være store XML-dokumenter på flere hundrede megabyte.
»Typisk indlæser man det, og så kopierer man det for eksempelvis at sikre, at der ikke er tegnsætproblemer, eller man skal trække noget tekst ud. Det er ikke ualmindeligt, at man indlæser sin tekst 6-8 gange i hukommelsen, og det er et problem, hvis det er et dokument på 200 megabyte,« siger Kees Jan Koster.
Her vil man som programmør kunne undgå det ved i stedet af oprette filen som en stream med en læsebuffer, så man kun indlæser en del af filen, når man skal bruge den, så man kan arbejde på et meget mindre område af hukommelsen.
Garbage collection er nemlig ikke særlig egnet til at håndtere det, der kaldes 'humongous objects', hvilket dækker over objekter i hukommelsen, der er så store, at garbage collectoren ikke bare kan flytte rundt på dem.
»Ideelt set, så bør du have meget få humongous object, og de bør være kortlivede,« siger Monica Beckwith, der er selvstændig konsulent og arbejder med blandt andet optimering af garbage collection i Java.
Objects kommer ikke i vejen
På JDK.IO-konferencen fortalte hun om garbage collectoren G1, der bliver den nye standard-garbage collector i Java 9. Den har blandt andet fået en metode til at håndtere humongous objects, som dog reelt blot indebærer, at garbage collectoren er klar over dem, og kan afsætte den fornødne plads til, at de ikke kommer i vejen.
Med G1 vil et humongous object være defineret ud fra den samlede mængde hukommelse, der er til rådighed. G1 opdeler hukommelsen som en heap i 2.048 regioner. Størrelsen af hver region vil variere fra system til system, men et object kategoriseres som humongous, hvis det er større end eller lig med halvdelen af størrelsen på en region.
Hvis objektet er større end en hel region, så bliver det håndteret som en humongous region. Det er reelt områder, som ikke bliver garbage collected.
Derudover vil G1 garbage collectoren prøve at optimere sig selv undervejs. Det betyder blandt andet, at den ud fra, hvor lang tid det tog at lave de tidligere kørsler, vil på at finde frem til, hvor hyppigt den skal køre de næste.
»Hvis du har brugt de tidligere garbage collectorer, så er du nok vant til at skulle finjustere dem. Med G1 er det bedre at lade den gøre det for dig. Du bør ikke pille ved noget, medmindre du er helt sikker på, at det vil hjælpe,« siger Monica Beckwith.
Java 9 kommer også til at indeholde Jigsaw, som gør det muligt at reducere, hvor meget af hele Java-platformen der skal pakkes med for at køre en applikation. Det kan også være nyttigt på meget små enheder med begrænset hukommelse, fordi selve den virtuelle maskine med applikationen ellers kan fylde så meget, at styresystemet bliver nødt til at bruge swap og lagre en del af dét, der skulle have ligget i hukommelsen, på disken.
Styresystemerne er i dag ganske gode til at placere de mindst brugte dele af en applikation i swap-lagret, men hvis den virtuelle maskine fylder så meget, at man overskrider en svært identificerbar tærskel, så kan det føre til uforudsigelig ydelse.
»Vi prøvede at måle det på en applikation ved at have to get-funktioner, vi målte på. Det gik enten vildt hurtigt, eller også tog det to sekunder, fordi det lå i swap,« forklarede Kees Jan Koster.

...men det er dyrt at lave god journalistik. Derfor beder vi dig overveje at tegne abonnement på Version2.
Digitaliseringen buldrer derudaf, og it-folkene tegner fremtidens Danmark. Derfor er det vigtigere end nogensinde med et kvalificeret bud på, hvordan it bedst kan være med til at udvikle det danske samfund og erhvervsliv.
Og der har aldrig været mere akut brug for en kritisk vagthund, der råber op, når der tages forkerte it-beslutninger.
Den rolle har Version2 indtaget siden 2006 - og det bliver vi ved med.