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.
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.
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.
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.
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.
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.