operativsystemer og programvare

Det 30 år gamle Java-språket bruker unødvendige ressurser – modernisering er på vei

Et av verdens største programmeringsspråk, Java, er på vei med mer effektive algoritmer i kjernen av språket. Det kan øke ytelsen og potensielt redusere ressursbruken i en tid hvor IT skrever stadig mer energi.

Sammen med kollegaer i Oracle har Brian Goetz i Oracle i ti år arbeidet med å løse Javas problem med tregt minne. Nå nærmer det seg første forsiktige forslag.
Sammen med kollegaer i Oracle har Brian Goetz i Oracle i ti år arbeidet med å løse Javas problem med tregt minne. Nå nærmer det seg første forsiktige forslag.

Vårt forbruk av data har en massiv bieffekt: et enormt forbruk av energi. I januar varslet Det internasjonale energibyrået (IEA) at det globale forbruket av strøm i datasentre vil mer enn dobles fra 2022 til 2026.

Programmeringsverdenen ser på hvordan mer effektive algoritmer kan kutte noe av energiforbruket. Når det gjelder et av verdens mest utbredte programmeringsspråk, Java, som brukes på milliarder av enheter verden over, har utviklere i ti år jobbet med å redusere ressursbruken. Dette krever at man løser en spesifikk egenskap som har eksistert siden språket ble utviklet.

I Java er det sentrale elementet et objekt som består av datafelt som kan inneholde verdier eller peke på andre objekter. For 30 år siden, da Java så dagens lys, tok det omtrent like lang tid å hente én byte fra minnet som det tok CPU-en å utføre en pluss- eller multiplikasjonsoperasjon. Men i dag er det et stort gap mellom tiden det tar å hente data fra minnet og tiden CPU-en bruker. Dette er spesielt et problem i Java.

Nå er problemet på vei til å bli løst, og Bernard Traversat, nestleder for Java-utvikling i Oracle, sier at løsningen også har bieffekter, som for eksempel mer effektiv opprydding i minnet, noe som også kan spare ressurser. Oracle forsøker også å gjøre språket mer effektivt på andre områder, forteller han til Version 2.

Illustrasjon: Ing.dk

RAM er flaskehalsen

RAM – minne – og CPU har altså beveget seg i hver sin retning når det gjelder ytelse. Professor Jan Madsen ved Danmarks Tekniske Universitet (DTU) forklarer at de mange optimaliseringene som har vært mulige på CPU-siden, ikke har en tilsvarende utvikling på RAM-siden. I programvareverdenen sies det ofte at en minneoperasjon tar tusen ganger lengre tid enn en CPU-operasjon.

– Om det akkurat er en faktor på tusen, det avhenger av teknologien og andre forhold, men det er en betydelig forskjell, sier han.

Inne i RAM-komponenten er det en ladning som signaliserer 0 eller 1, og denne «fordamper», eller diffunderer, som det korrekt heter på fagspråket. Derfor må ladningen fornyes jevnlig, og dette tar også tid.

Madsen tror ikke vi vil få mye raskere RAM i nær fremtid. I stedet er dagens løsning å flytte CPU-ene nærmere minnet, slik vi ser i superdatamaskiner. I mellomtiden har CPU-en blitt utstyrt med eget hurtigminne, L1-, L2- og L3-cache. Dette imøtekommer problemet ved å kopiere mange bytes fra minnet i én operasjon.

Tanken er at hvis programmet trenger en byte, er det sannsynlig at programmet også vil trenge byten ved siden av. Men forutsetningen er at programmets data er lagret tett sammen i minnet. Dette har vært Javas store problem – at vanlige objekters verdier ofte er spredt rundt i minnet. Dermed fungerer ikke cache-trikset.

Sammenkoblingen av data og andre tiltak gir betydelig bedre ytelse på en rekke områder, fortalte Javas Brian Goetz på konferansen Java Language Summit, som nylig ble avholdt. Identitetsklasser er Javas klassiske objekter, mens verdiklasser er de nye, kompakte objektene. Illustrasjon: Oracle/Youtube
Sammenkoblingen av data og andre tiltak gir betydelig bedre ytelse på en rekke områder, fortalte Javas Brian Goetz på konferansen Java Language Summit, som nylig ble avholdt. Identitetsklasser er Javas klassiske objekter, mens verdiklasser er de nye, kompakte objektene.

Forutsett av oppfinneren

Javas svakhet ble forutsett av oppfinneren James Gosling for snart 30 år siden. Den nåværende sjefutvikleren for Java, Brian Goetz, har tidligere fortalt Version 2 at på det tidspunktet var det så mange nyvinninger i språket at man prioriterte andre utfordringer.

Gosling har uttalt at minneproblemet var like komplisert som «seks sammenfiltrede doktorgradsavhandlinger», og Goetz kaller forandringen «episk». På Java Language Summit, som nylig ble arrangert i California i USA, kunngjorde Goetz at en første prøveversjon av et kjøringsmiljø som løser problemene, snart er klar.

I dagens Java er datafeltene i objektene, som nevnt, spredt over hele minnet. Dette blir særlig utfordrende når det gjelder arrays (lister), som ikke utgjør en pen, sammenhengende rekke med celler i minnet, men derimot består av elementer som peker til nye objektgrafer, som altså kan befinne seg et annet sted.

Lister av objekter (arrays) har en tendens til å bli spredt utover hele minnet i Java, der hvert element peker mot et nytt sted. Med verdiklasser kan data samles i én sammenhengende rekke av minneceller, som kan kopieres til CPU-ens cache, med betydelige ytelsesforbedringer som resultat. Illustrasjon: Oracle/Youtube
Lister av objekter (arrays) har en tendens til å bli spredt utover hele minnet i Java, der hvert element peker mot et nytt sted. Med verdiklasser kan data samles i én sammenhengende rekke av minneceller, som kan kopieres til CPU-ens cache, med betydelige ytelsesforbedringer som resultat.

Bortfall av identitet løser flaskehalsen

Løsningen i Java er å introdusere en ny type klasse – en verdiklasse.

Verdiklasser ligner Javas vanlige klasser, med én avgjørende forskjell: De har ingen identitet. Dette kan virke litt komplisert, men det er nettopp denne egenskapen som gjør det mulig å lagre klassene tett sammen. Det betyr at ingen verdiklasse er unik, og to verdiklasser med samme feltverdier er like, vurdert med ==-operatoren, som ellers sammenligner objektidentitet, altså om de to referansene peker på samme sted i minnet.

Goetz forklarte det slik i sitt innlegg:

– Det som særlig kjennetegner forskjellen mellom verdiklasser og identitetsklasser under kjøring, er at de kan kopieres fritt. Kjøringsmiljøet kan dele opp et verdiobjekt i dets felter, sende feltene rundt til CPU-ens registre, og gjenskape objektet når det er behov for det.

Dette åpner for optimaliseringer, som å legge verdiobjektet på stacken – kjøremiljøets eget minne som opererer raskere enn det «store» minnet, heap. Skalarisering, hvor operasjoner parallelliseres med moderne CPU-ers vektorfasiliteter (også kjent som SIMD, single instruction – multiple data), er en annen mulighet.

Sånn kan flaskehalsen fjernes i fremtiden

Professor Jan Madsen fra Danmarks Tekniske Universitet (DTU) forklarer om RAM og CPU-cache:

Den RAM som vi normalt kaller hovedminne, er dynamisk RAM, eller DRAM, som må oppdatere verdiene sine jevnlig. Den enkelte RAM-cellen (som kan lagre 1 bit) er veldig liten – noe som gjør at man kan ha mange på et gitt areal. Ulempen er at den ikke er like rask som statisk RAM, eller SRAM (som ikke krever at minnet friskes opp – og derfor kan svare raskere). Her tar den enkelte RAM-cellen mye mer plass, og man kan derfor ikke ha like mange på et gitt areal. SRAM brukes som cache mellom hovedminnet og CPU-en. Det finnes vanligvis tre nivåer av cache, L1, L2 og L3. L1 ligger på CPU-en, mens de to andre ligger utenfor.

I fremtiden skal RAM være nærmere CPU-en. Det gjelder spesielt den typen RAM som kalles Processor-In-Memory (PIM). Denne typen er i dag mye brukt i forbindelse med superdatamaskiner, hvor selve brikken produseres i tre dimensjoner, slik at RAM og CPU (flere av dem) er tett koblet sammen over hverandre.

Artikkelen ble først publisert på Ingeniøren Version 2 for deres abonnenter. Den er tilgjengelig på norsk for abonnenter av Ekstra gjennom vår samarbeidsavtale.

Powered by Labrador CMS