Kan man lave memory leaks i Java?

Det ser ud til, at der er et memory leak i vores applikation. Hver gang, man udfører en bestemt handling, bliver der brugt mere og mere hukommelse, og til sidst løber man helt tør og må genstarte applikationen. Av av av. Takket være Javas garbage collection, der klarer det meste af oprydningen, er det heldigvis en sjældent forekommende situation. Men hvis vi udviklere på et tidspunkt har fået applikationen skruet sådan sammen, at vi står og holder en reference til noget, man burde have smidt væk, eller som slet ikke skulle have været der i første omgang, ja så kan JVM'en ikke klare ærterne for en.
 
Hvor kan man så begynde at lede efter problemet' Jeg fik installeret værktøjet JProfiler, der i hvert fald plejer at være en udmærket til at finde CPU-bottlenecks og så ud til at have nogle tilsvarende fornuftige features til at søge efter memory leaks. Jeg kunne i hvert fald hurtigt konstatere, at det, der fyldte i hukommelsen, var tekststrenge. Men hvem lavede dem, og hvem holdt referencerne til dem' 
 
Se, der var jo temmeligt mange strenge, og de fleste af dem blev hurtigt smidt væk igen efter at være sendt afsted til klientside-applikationen, så det var lidt en nål i en høstak, jeg skulle finde. Men i betragtning af, at jeg havde et eksempel, hvor der indenfor ret kort tid blev brugt exceptionelt meget hukommelse, måtte det da være en temmeligt stor knappenål? Altså kunne jeg jo da begynde at kigge efter usædvanligt store strenge... Og jeg så nogle mærkelige ting i profileren. Det så ud som om, der lå adskillige tomme strenge og pegede på nogle meget store char-arrays. Det kunne jo godt være tilfældet med ubetænksom brug af substring-funktionen, der ikke kopierer det underliggende array, men blot kopierer referencen til det. Så jeg gik i gang med en debugger i stedet for at få verificeret, at det var der, problemet lå.
 
Irriterende nok viste det sig, at jeg med debuggeren slet ikke kunne genskabe den situation, som profileren viste. Der var ikke nogen, som gik og lavede tomme strenge med underliggende mega-arrays. Profileren må have ført mig på vildspor. Nå, men ved at browse lidt tilfældigt igennem de tekststrenge, der lå i hukommelsen, fik jeg fornemmelsen af, at der var temmeligt mange attributter i den HTML-DOM, vi gik og parsede. Så kunne jeg sætte noget kode ind et passende sted, der kunne logge hvor mange attributter, der blev lavet. Halløjsa! Det så ud til at vokse med en faktor 10 hver gang, man klikkede i applikationen. Det så altså lidt suspekt ud, især da HTML-elementerne efterhånden begyndte at indeholde tusindvis af ens attributter.
 
Som i så mange andre fejlsituationer viste problemet sig at bestå af to underliggende fejl. Den ene, at det sted, der genererede den HTML-tekst, der skulle parses, kom til at indsætte noget defekt HTML, når den mødte elementer (ikke tags, men altså DOM-knuder) med navne som "/IMG" fordi den oprindelige sides programmør har glemt, at man ikke må lukke IMG-tags. Den anden fejl var, at HTML-parseren gladeligt parsede flere ens attributter og proppede dem ind i DOM'en; det gør f.eks. IE ikke. Hvis en af de to fejl ikke havde været der, havde den anden ikke gjort nogen skade... Men det var åbenbart en Tycho Brahes dag ![Eksternt billede](http://www.version2.dk/uploads/smil3dbd4e398ff7b.gif" alt=")

Kommentarer (31)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Jens Madsen

"Java er én stor memory leak, som kun kan 'patches' ved at bruge et native compiled sprog."

Jeg kan ikke være mere enig!

Der er flere årsager. Mange Java programmører, tror netop ikke, at der kan forekomme memory leaks. Derfor, er de ikke opmærksomme på hvordan hukommelsen bruges. Men, jeg tror det også er smækfyldt med memory leaks i standard komponenterne, for alle java applikationer jeg har set vokser.

I princippet, sker en "oprydning" i sprog som java. Denne oprydning sker ikke uafbrudt, og du kan nemt nå voldsomt forbrug, inden den udføres. Laver du et program, der hurtigt bruger masser af hukommelse og ikke har nogle pointere til denne hukommelse, så bliver hukommelsen fyldt op, inden garbage kollektoren kaldes. Et andet problem, er at programmørerne overhovedet ikke frigiver deres lager - der er jo ingen "frigivningskald". Du skal frigive dit lager, således du på ingen måder, kan få adgang til dette. Gemmer du en stor bunke data, og er der via en glemt pointer adgang til denne datamængde, så vil forbruget stige. Først når du effektivt udryder din mulighed for at få adgang, vil garbage kollektoren kunne fjerne forbruget. Hvis der findes måde for access, så skal det jo gemmes.

Mit syn på Java, og gabage kollektion, er at det er noget skidt. Årsangen ligger eksempelvis i det stokastiske. Man styrer ikke, som programmør, hvornår garbage kollektoren skal kaldes (det kan være muligt at kalde manuelt). Dermed, er det som sker, på sin vis ikke mere deterministisk. Det ram du bruger, og rammen der er til rådighed, er en "tilfældig størrelse". Det kan være svært, at bede om, at få lagerforbruget kortlagt - hvis du ikke kalder garbage kollektoren først, er resultatet tilfældigt, og kalder du den først, så får du et for pesimistisk resultat, da applikationen kan anvende bunker af hukommelse som andre ikke kan bruge, inden garbage kollektoren kaldes.

Så det er rigtigt meget korrekt i, at Java er en stor memory leak.

Jeg foretrækker, et sprog hvor brugen af pointere, er struktureret. Det vil sige, at du arbejder i strukturer - som for structs, og i operativsystemet, har mulighed for kataloger, underkataloger osv. og at dette oprettes, således det er struktureret brug. De fleste sprog med pointere, er totalt ustrukturerede i deres brug af pointere, og du siger bare at jeg vil gemme en integer - og vupti, så får du gemt en integer. Det rette, som jeg ser det, er at først lave et arkiv, hvori den pågældende integer skal gemmes. Ellers bliver den gulvarkiveret. Og det er så Java. Indimellem skal gulvet rydes op. Struktureret brug af pointere, kan ske ved at oprette strukturer, der f.eks. er rekursive, og derved uendeligt dybe, eller ved at have systemer som på en harddisk, hvor du dynamisk kan oprette kataloger. Den pågældende uendelige struktur, eller harddisk, vil nu tillade, at du kan referere til en bestemt placering i dit strukturerede "uendelige" arkiv, hvor du kan gemme dine data. Først, når du gemmer data, fylder det reelt. Du kan slette hele arkivet, ved at slette roden på strukturen, eller en underdel, ved at slette fra et vist punkt (som f.eks. deltree). Dette er en mere struktureret måde, og du har altid adgang til dine data via dit arkiv. Du behøver ikke, at bruge "pointere", men kan bruge det. Sletter du data, gør du det i arkivet. Det kan ske gennem en pointer. En pointer, kan ikke direkte indeholde data, og derfor er ingen oprydning. I stedet, så peger den på data, i et arkiv. Virker som en index pointer, der peger på et bestemt navn, eller katalog, på din harddisk.

Ovenstående systemer, er langt mere strukturerede, og fører ikke til samme "uorden". Det hele er deterministisk, og struktureret. Du kan få at vide hvor meget lager der bruges for en struktur, ved at undersøge antallet af elementer på dens rod. Du kan have mange strukturer i dit program. Du får derfor gode muligheder, for at undersøge forbruget, for de enkelte rutiner, og for de dynamiske strukturer som programmet er opbygget i enkeltvis. Du kan også undersøge det for en undernode, og få lagerforbruget for denne, og de undernodes der er under den.

Strukturmæssigt, er en mulighed at tænke på struct i c++, og lave en ulovlig rekursion tilbage til hovedtypen, således strukturen gentages. Derved opnås uendeligt forbrug. Men hvis det kun fylder noget, når du putter data i denne struktur, så vi du opnå en mulighed for uendelig plads, der kun fylder hvis det bruges. Det kan anvendes som grundarkiv. Man kan også have mulighed for et system som på harddisk, hvor du kan tilføje "kataloger", og "underkataloger" dynamisk, der nærmest svarer til ovenstående, men hvor du har mulighed for at opbygge dine structs dynamisk meddens programmet kører. Det er ikke helt så velegnet for kompilere (medfører større kode). Samtidigt, kan det føre til større rod, end når alt er synligt, i programmet fra starten. En compiler, vil normalt virke så det ikke kan oprettes dynamisk, men strukturerne deffineres, som data placeres i - da det er "compiler måden".

Jeg ved ikke, om der findes java programmer uden memory leak. Men jeg har tjekket flere, hvor det tilsyneladende blot var kæmpe forbrug, og hvor det trods alt stabiliseredes efter nogen timer. Vi må dog huske, at det ikke er nogen garanti for, at det ikke pludseligt, en gang i fremtiden, opstår en situation, hvor hukommelsen stiger uden grænse. Dette kan en "test" uden kendskab til programmet, ikke teste. Med mindre den kører i så mange år, at memory leaken opstår. Og det er måske sjældent - og stokastisk.

  • 0
  • 0
Martin Rytter

Jens, Mark:

Og det er simpelthen garbage collection der er skyld i alle disse onder. Det vil sige at sprog most lisp, ruby, c#, perl, php og mange flere også er skyld i "et stort memory leak".

Forstå mig ret. Jeg er ikke Java prædikant eller noget der ligner. Men jeres ammunition er altså for billig.

> En compiler, vil normalt virke så det ikke kan oprettes dynamisk, men strukturerne deffineres, som data placeres i - da det er "compiler måden".

Så du bruger aldrig "new" eller malloc? Det skal der nok komme velstruktureret kode ud af.

/mrj

  • 0
  • 0
Anders Reinhardt Hansen

Hold da op for en sur gang opkast. Hvor har du alle dine referencer du bygger denne velunderbyggede teori på?
Det er altså noget af en urban myth det med at java bruger meget mere hukommelse end så meget andet.
Fakta er at der er et overhead for at starte en java applikation op hvis den bruger mange eksterne frameworks, og derfor vil selv små java programmer kunne bruge meget ram. Når det så er sagt er det ikke lineært hvor meget ram java bruger.
Og det er også ekstremt meget op til programmøren. Godt programmeret lille ramforbrug, dårligt programmeret stort ramforbrug. Dette går altså igen i mange andre sprog så hold your horses mate.
En anden pointe er også at der er adskillige Virtual machines derude som afvikler java kode, Suns, microsofts(eeewwww, ringe ringe ringe), BEA, IBM, Oracle med mange flere.
Disse er optimerede til forskellige ting, men IBM's, Oracles og BEA's performer rigtig godt til enterprise computing. I nogle tilfælde performer JVM endda bedre en optimeret C-kode, f.eks. ved numeriske beregninger: http://www.itu.dk/people/sestoft/smp2/csharpspeed.pdf

For så at tage det lidt mere tekniske; Du skelner altså ikke mellem garbage collection og deallocation. JVM beslutter selv hvornår den skal garbage collecte, men programmøren beslutter hvornår en variabel stadig er refereret (eller i scope). Og det er vigtigt at skelne imellem.
Tag nu lige at komme ned af din høje hest og prøv java kode i virkeligheden. Vi er faktisk nogle der lever ganske godt af det, og med yderst tilfredse kunder.

  • 0
  • 0
Jens Madsen

"et for pesimistisk resultat" - naturligvis for optimistisk, da der bruges mere lager, end umiddelbart efter kald af garbage kollektoren.

Selvom man kan teste Java programmer, til at måske stabilisere sig i forbrug, så er forbruget et resultat af en stokastisk process, der bestemmes af hvor meget der bruges, inden garbage kollektoren "tilfældigvis" kaldes. Dertil, kan det afhænge af kode, og langtfra alt kode kalde uafbrudt. Konklussionen er, at der ikke findes nogen top. Med andre ord, så er Java en hukommelses leak, og det skyldes tilfælde, at den over f.eks. to timer, ikke giver uendelig forbrug. Havde du haft en computer, der udførte flere linier, og kaldte garbage kollektoren sjældnere, så vil forbruget være større, da mere vil hobe sig op. Det er dermed genneralt ikke normalt en beviselig max størrelse. Og derfor er det en leak. Kun "stokastisk" set, fungere det.

Naturligvis afhænger det også af programmet, og et program, der ikke står og bruger, og senere frigiver hukommelse (statisk forbrug) vil teoretisk kunne opnå konstant forbrug. Det er dog meget teoretisk, på grund af biblioteker.

  • 0
  • 0
Jens Madsen

Jeg har ikke nogen "bog" som det står i. Det kommer fra et forholdsvis ellementært Java kursus, hvor læren forklarede meget grundigt, at hvis man hurtigt oprettede plads, og frigav plads, så vil det hobe sig op - og garbage kollektoren vil ikke nødvendigvis blive kaldt. Derfor, vil opstå et stort forbrug. Hvis der er et maksimum for applikationen, som Java ved af, så vil den kalde garbage kollektoren, når dette maksimum nås. Der skal derfor principielt sættes et teoretisk maksimum, for det fungerer. Og hukommelesforbruget, er teoretisk "næsten" altid op til dette maksimum. Man kan ikke forvente, der bruges mindre - med mindre du selv kalder en garbage kollektor, med jævne mellemrum, således du sikrer dig, at det rydes op inden du får langt for meget på.

Da det var et grundlæggende java kursus, på kun få dage, betragtede jeg det for elementær viden, at gabage kollektion fungerede på den måde, og jeg har ikke undersøgt om der skulle findes referencer til lærens påstand. Men jeg har svært at se, hvordan det kan fungere på anden måde. Noget, skal kalde garbage kollektoren. Og dette sker, når det er mangel på hukommelse. Indtil da, vil hukommelsen blive brugt. Reelt betyder det i mange tilfælde at hukommelsen bruges indtil manglen indtræder, og f.eks. et C++ program, eller andre programmer, der ikke anvender samme garbage kollektor, vil ikke kunne reservere hukommelsen fordi den er i brug af Java applikationen. Når C++ derimod, at reservere den først - før Java får fat på den, så går det. Det kan man ikke genneralt forvente.

Teoretisk, er forbruget dermed max. Eller indentisk med memory leak. I princippet vil Java applikationen fungere, men alt andet vil mangle lagerplads.

Løsningen er at lægge garbage kollektoren under operativsystemet. Så længe programmerne kører under samme garbage kollektor, er ikke problemet.

Java, er derfor så godt som en hukommelsesleak, der dog er så robust, at leaken kun går ud over alt andet (operativsystem, C++ osv.) De vil ikke have mere hukommelse, end det Java har ladet dem få.

Kan ikke umiddelbart gennemskue hvad det sker, hvis to javaer kører samtidig, eller en java, plus en C med garbage kollektor. Måske er resultatet teoretisk kaos, ligesom hvis to regulerende termostater er i samme rum.

  • 0
  • 0
Anders Reinhardt Hansen

Så vidt jeg har forstået det er det rigtigt at gc kører når den ikke kan allokerer mere inden for young generation collection, som er et store for kort-livs objekter. Derudover kører der en baggrunds collector som tager sig af garbage collection on the fly.
Så du har ikke helt ret, det er ikke hele max hukommelsen for en applikation der bruges før at der garbage collectes men derimod en %-del af den totale hukommelse.
Man kan selv vælge at gøre størrelsen af young generation mindre, med deraf følgende oftere garbage collection eller man kan vælge at gøre den større hvilket medfører større ramforbrug, og længere mellem gc(og dermed tungere gc).
Derudover kan du kalde system.gc() lige så ofte du vil med dertil hørende smadring af performance.
Pointen er vel at du står og råber op om noget som du ikke ved særlig meget empirisk om, og kun en lille smule teoretisk.
Ifølge dig burde vi vel heller ikke cache database kald overhovedet for det bruger for meget ram og der er ikke andre apllikationer der kan gå ind og bruge database cachen's ram.

  • 0
  • 0
Jens Madsen

Din artikkel er meget god, men umiddelbart kunne jeg ikke se - eller gennemskue - hvor det præcist var beskrevet, hvordan garbage kollektoren skulle undgå problemet. I princippet, kan man forestille sig flere metoder, så det er begrænset hvor meget ekstra forbruget er - f.eks. at kalde garbage kollektor, når forbruget bliver 30% større end det eksisterende, samt hvis det når et maksimum - derved burde vi kunne sikre det ikke blivere mere end 30% for stort. Men, hvilken metode, der bruges, kunne jeg ikke umiddelbart gennemskue.

Min modstand mod garbage kollektors, skyldes ikke at det ikke fungerer. Det skyldes alene, at jeg ikke syntes om der sker noget tilfældigt, jeg ikke har kontrol over. Jeg vil gerne vide eksakt, hvor stort forbruget er på et vilkårligt tidspunkt, og jeg vil gerne kunne få det for en vikårlig "struktur" af data. Jeg er også imod, at man ustruktureret bare kan gemme en "integer", eller en anden struktur, og gemme en pointer til den. Data, skal opbevares i et arkiv. Og kun hvis arkivet slettes, forsvinder data. Ikke noget med, at man bare sletter, fordi alle har "glemt" hvor data er. Der skal altid, være adgang til arkivet, og slettes de her, slettes det for alle pegere. Det er sådan at virkeligheden er. Java, er meget langt fra virkeligheden. Tænk, om dine forældre døde, fordi du glemte dem? Ikke rart at tænke på. Selvom man måske ikke lige har mulighed for at se dem, er det rart at vide, at de nok er til. I java, vil en "morder" gå rundt, og ryde op. For at de ikke skal æde af pension eller bistand. Sådan skal vi aldrig have det.

Min modstand mod Java, og programmer der har garbage kollektor, er derfor af principiel karakter. Det er modstand mod kaos. Modstand mod, at man skal udryde data, bare fordi man ikke har adgang, og modstand mod at data ikke er struktureret, og står i et arkiv. Data bør have et arkiv, der opbevarer data - og pointere opbevarer ikke data, men peger på arkivet. Det er struktur, og sådan verden er opbygget.

Garbage kollektion er rod. En slags overbygning på normale ustrukturerede metoder kendt fra C (pointere), hvor man bare kreerer data eller objekte, uden struktur. Man opdagede, at det var skidt, og programmørerne glemte at slette data, hvorefter der blev ansat en rengøringsassistent til at ryde op. Man fik aldrig orden på tingene, og fat på et arkiv. Data ligger stadigt og roder på gulvet. Struktur er, at man netop ikke har denne rod, men opbevarer data struktureret og ordentligt, i et arkiv med system.

  • 0
  • 0
Anders Reinhardt Hansen

Bemærkninger á la "I java, vil en "morder" gå rundt, og ryde op" er meget hæmmende for en fornuftig diskussion af for og imod garbage collection.
Fakta er at du kan konfigurere meget af det her. Fakta er også at grundet genbrug af objekter og caching af eksisterende data er java ofte hurtigere end ikke virtualiseret kode.
Der findes også andre parametre end footprint (ram forbrug) som man skal vurdere en applikation på. Ram er faktisk en af de ressourcer du kan få forholdsvis meget af for en billig penge.
Og som du selv siger forbruget stabiliseres over tid.
Jeg mener ikke at denne diskussion fører videre, og det er tydeligt jvf dine overfor nævnte analogier at du ikke egentlig er interreseret i en meningsudveksling. Men mere, jeg kan ikke lide det og derfor kan jeg ikke lide det.
C-kode var heller ikke populært engang fordi at maskin kode var det eneste rigtige. Men paradigmer kommer og går, du kan så gå og glæde dig til at virtualiserings paradigmet bliver erstattet med simplicitets paradigmet, når knapheden på ram begynder at melde sig.

  • 0
  • 0
Dennis Krøger

"Tænk, om dine forældre døde, fordi du glemte dem? Ikke rart at tænke på. Selvom man måske ikke lige har mulighed for at se dem, er det rart at vide, at de nok er til. I java, vil en "morder" gå rundt, og ryde op. For at de ikke skal æde af pension eller bistand. Sådan skal vi aldrig have det."

WTF? Hvad har det at gøre med et framework? Du må hellere lade være med at tænde din computer mere, når du slukker den glemmer den jo alt i hukommelsen, og så myrder du jo adskillige familier af data...

Du eftersøger bevis, mens du samtidig slynger utallige uigennemtænkte tåbeligheder ud...

  • 0
  • 0
Jens Madsen

"Ifølge dig burde vi vel heller ikke cache database kald overhovedet for det bruger for meget ram og der er ikke andre apllikationer der kan gå ind og bruge database cachen's ram."

Der er ingen der siger, at cache bruger meget ram.

Hvis du har en deterministisk størrelse af cache, er et i ordent for mig. Men det er lidt om snakken.

Problemet for mig, ligger specielt i hardware - såsom processoren. Dennes cache gør, at det er meget svært at vide præcist hvor lang tid noget tager. Derfor, er svært at garantere at realtids software fungerer. Nogle microcontrolere, fungerer eksakt, således hver indstruktion tager et antal givet antal cycles, der kan opslås i en tabel. Der er ingen cache, men data tages fra program lageret direkte. Hvis der er wait states, har man selv lagt dem ind. Et sådant system, er nemmere at analysere, og dermed sikre fungerer.

Imidlertid, er det ikke umuligt, for systemer med cache. Du kan godt tage et "worst-case", hvor du eksempelvis antager, at cachen tømmes, på bestemte tidspunkter, eller at den simpelthen ikke er der. Hvis et sådant worst-case er muligt, så er det nok for mig. Hvis du kan opsætte et worst case scenarie, og sikre dig at dette fungerer, er det nok for mig.

At CPU'en så kører ekstra stærkt, og kan udføre en masse ting, som ikke nødvendigvis skal klares indenfor nogle tidsmæssige krav, er bare i orden. Det væsentlige er, at et maksimum eksisterer.

For garbage kollektion, er der også et maksimum forbrug - eller det kan sættes, men det er en process der tager tid, og er besværlig. Jeg syntes den er upraktisk, men ikke nødvendigvis ulovlig.

Jeg har aldrig lavet rigtigt java kode. En af årsagerne skyldes jeg har arbejdet, hvor programmeringssproget var Java. Og det fungerede håbløst. Ofte, gjorde softwaren ting, som programmørerne hårdnakket nægtede at have kodet. Det var ikke kompatibelt med fremtidige versioner og da der kom ny Java, var intet der fungerede. Koden kunne ikke ændres. Og man kunne fortsætte. Indtastedes noget, forsvandt det ofte bag de andre vinduer. Eller, måske blev der ændret i data når der blev trykket OK. Og det var ofte umuligt at rette. Det gav et utroligt dårligt indtryk af Java, at jeg besluttede ikke at bruge sproget, og anså ikke grund til yderligere at lære det.

Desuden syntes jeg ikke at viden om hvordan det virker - og at man er ekspert - er væsentligt. Problemet i dag, er i høj grad, at eksperterne ikke er kritiske nok. Normale brugere, er ofte mere kritiske. En ekspert ses ofte, at hævde noget fungerer trods samtlige brugere kan se at skærmen slettes når noget tastes ind. Det er totalt uhørt, hvad eksperter påstår fungerer.

Men jeg er glade for, at der findes eksperter, der kan give os "idioter" svar på tiltale!

  • 0
  • 0
Anders Reinhardt Hansen

"Ofte, gjorde softwaren ting, som programmørerne hårdnakket nægtede at have kodet. Det var ikke kompatibelt med fremtidige versioner og da der kom ny Java, var intet der fungerede"

Det er jo en udvikler, jeg ALDRIG ville ansætte. Computere er ikke objekter der gør underlige ting, de er deterministiske, og der er altid en grund til deres reaktion. Man skal ikke være en slags alternativ behandler der siger at tingene opfører sig underligt. Man skal undersøge hvorfor de gør det og så rette det så de ikke gør det.
Det er fuldstændig psudo-videnskabeligt det du fyrer af, det ovennævnte citat kunne ligeså godt stamme fra kode skrevet i c af en håbløs programmør som i java af en håbløs programmør. Det jo absurd at kalde et framework for dårligt fordi at det gør ting man ikke har forudset. Ansæt nogle bedre folk i jeres firma og lad være med at kaste mere med sten.
Seriøse udviklere tester med rigtige brugere som melder tilbage med fejl, disse fejl bliver så rettet eller udskudt til en ny version af koden.

  • 0
  • 0
Jens Madsen

"(ram forbrug) som man skal vurdere en applikation på. Ram er faktisk en af de ressourcer du kan få forholdsvis meget af for en billig penge."

Det væsentlige for ram forbrug, er store O funktionen af forbruget. En hukommelsesleak kan ikke accepteres. En eksponentiel store O funktion, således dobbelt så mange data, fører til million gange større forbrug, kan ikke accepteres. En konstant, betyder ikke det store. Derfor betyder forbruget meget - og du bør ikke lave f.eks. rekursive funktioner, eller objekte, der har en O(n*n) dybde. Programmører burde altid opskrive ram forbruget, som minimum i størrelsesorden, for deres applikation, så man kan få overblik over forbruget, og at der ikke er "bomber". Ligesom ved CPU-hastighed, hvor der kan være hastighedsmæssige bomber, ses også at f.eks. rekursive procedurer, kan have en dybde der fører til ram-bombe.

Vi skal have lov at være uenige om, hvorvidt javas brug af hukommelse er godt - eller om det kunne have været på en bedre måde. Som jeg ser det, er det ustruktureret at gemme data, uden de er i en opskrevet struktur.

Grunden til min analogi med "virkeligheden", var episoder af mit liv, hvor "noget" åndeligt formentligt, udsatte mig for ting jeg udsatte computeren for. Det var en særdeles mystisk oplevelse, der ikke kan gives forklaring på. Som resultat, blev jeg kortvarrigt bange for, at såvel programmere, som at udvikle elektronik, og måtte holde pause. Siden, har jeg forsøgt at vende opdagelserne positivt, til at søge at bruge strukturer, hvor computeren fungerer på en positiv måde, f.eks. ikke bliver stresset, ikke bruger for meget strøm, osv. og jeg syntes mine ting har fået bedre kvalitet deraf. Det er dog langtfra rart, at få hukommelsesnedbrud i ens egen hjerne fordi man har lavet en hukommelse der ikke fungerede. Det var som jeg ser det for skrappe "løjer". Men - måske dog noget jeg lærte ved.

  • 0
  • 0
Anders Reinhardt Hansen

"Grunden til min analogi med "virkeligheden", var episoder af mit liv, hvor "noget" åndeligt formentligt, udsatte mig for ting jeg udsatte computeren for. Det var en særdeles mystisk oplevelse, der ikke kan gives forklaring på"

Jeg siger ikke det følgende for at være grov over for dig. Men når du begynder at trække det spirituelle ind i en diskussion af ram-forbrug så er jeg sgu stået af. Det hænger altså ikke sammen. Jeg kommenterer ikke længere på dine indlæg.

  • 0
  • 0
Jens Madsen

"Jeg siger ikke det følgende for at være grov over for dig. Men når du begynder at trække det spirituelle ind i en diskussion af ram-forbrug så er jeg sgu stået af. Det hænger altså ikke sammen. Jeg kommenterer ikke længere på dine indlæg."

Jeg giver dig helt ret i, at det "spirituelle" ikke er en videnskabelig begrundelse. Men mange holdninger - også omkring programmering - skyldes ikke videnskab. Det er et spørgsmål om, hvad man syntes er flot, spændende, og hvordan man syntes om det. Det er ikke nødvendigvis en videnskab.

Jeg vil gerne kunne begrunde som videnskab, at det førte til større effektivitet, bedre programmering (hvad det så end er), hurtigere kodning, færre fejl osv. at ikke bruge Javas måde at håndtere pegere. Det må jeg indrømme, at jeg ikke kan. Måske dukker en gang en begrundelse op. Indtil nu, er det kun en fornemmelse af, at tingene har bedst, ved at stå på en pæn og struktureret måde i en arkiv. Jeg syntes - personligt - at det er nemmere at overskue et træ, hvis du deffinerer træets struktur, og opbevarer data i dette træ - fremfor at du har en række "noder" der ligger på en heap, og på grund af deres links deffinerer træet. Du kan umiddelbart se af koden at her er et træ, og hvordan dets struktur er, og du kan gå frem, tilbage, bruge index(pointere) til dele af træet, eller til noder. Det er kun et spørgsmål om overblik.

Enhver, kan påstå, at vi bedre kan finde data, på anden måde. Og at de bedre kan overskue sproget, som det er nu. Så er så spørgsmålet om de reelt kunne - hvis de fik begge muligheder. Mange har begrænsede muligheder, og må tage udgangspunkt i de muligheder som de har. Dette beviser dog ikke, at det eksisterende, altid er ideelt.

  • 0
  • 0
Jens Madsen

"Det er jo en udvikler, jeg ALDRIG ville ansætte. Computere er ikke objekter der gør underlige ting, de er deterministiske"

ja, vi havde mange programmører. For alle var det éns! Men hvis jeg skulle ansætte dem, var det nok ikke gået.

Et af problemerne med Java, var f.eks. at det var skrevet med bunker af processer. Nogle gange, kom éen process først. Andre gange, kom en anden process først. Måske var ikke de data, der skulle bruges, når processen blev udført - andre gange, var data der. Det kunne betyde, at visse ting nogen gange ikke virkede. Andre gange fungerede det. Java input boksen, kunne pludseligt forsvinde sporløst, og lagde sig typisk under en anden applikation. Det som man indtastede, kunne i nogle tilfælde pludseligt miste data. Og når man trykkede OK var ikke muligt at senere få udskrift så det kunne se det var forkert. Data forsvandt "ned i dybet", osv. Virksomhedens strategi var ofte, at det var et sikkerhedsproblem, hvis indtastede data kunne udskrives, og de skulle helst ikke ses. Vi brugte også moderne tools der lavede kode til eksempelvis brugergrænsefladen, og disse gav problemer - uden nogen reelt vidste meget om indholdet af den java de producerede.

Efter disse oplevelser, tror jeg det er bedst man tvinger programmeringssprogene til at være deterministiske, og at det hellerikke ved brug af mange processer, er muligt at opnå noget ikke deterministisk, med mindre det står på en måde i koden, så ingen har mulighed for at tage fejl - at her er noget ikke deterministisk, hvor koden må opføres sig tilfældig.

Idag, er det meget "mode" at tale om "god programmering", "skodprogrammering" osv. Min holdning er, at disse begreber ikke er gode. Det er langt bedre, med et sprog, der tvinger til god programmering. I sin tid, blev vi tvungen til, at gå bort fra goto. Derfor, gjorde man det. Det var muligt, at forbyde "dårlig latin", ved at forbyde det i sproget. Det er måden, at undgå dårlig kode. Lav et godt sprog. Det skal ikke kunne udføre dårlig kode, eller også skal man sidde med møj og besvær og skrive det i tydeligt tale så alle kan se det, og med masser af ord, så det bliver besværligt, og så må det reelt ikke bruges, med mindre det er begrundet og med god årsag.

  • 0
  • 0
Jarnis Bertelsen

Der går utroligt hurtigt religion i valg af programmeringssprog. Det virker som om mange programmører kun kan se fordelene ved det sprog de har brugt tid på at lære sig, i stedet for at se på fordele og ulemper ved de forskellige sprog.

Fordelene ved Java er mange, bla.:
-Nemt at lære (i forhold til C/C++)
-Stort og godt framework, der klarer utroligt mange opgaver for programmøren.
-Hurtigt at udvikle i.
-Cross platform p.g.a. JVM
-Stor sikkerhed mod traditionelle fejl som fx buffer-overruns

Det kommer selvfølgelig med en pris, hukommelsesforbrug er en af dem, performance er en anden. Der er måder at omgå disse ulemper (det påstås at være lavet en Quake 1 portering med bedre framerates end originalen) for en dygtig programmør, men i praksis er der ofte andre prioriteter som en Java programmør bruger sine resourcer på. Jeg er personligt glad for Java's garbage collection. Den sparer mig tid som jeg kan bruge på mere interresante ting, og jeg har endnu ikke stødt på en opgave, hvor den er et problem i praksis. Samtidig forhindrer den mig i at lave stupide fejl pga. manglende erfaring med hukommelsesstyring. Der et intet programmeringssprog, der kan beskytte fuldstændig mod en elendig programmør, men Java gør et godt stykke arbejde med at beskytte mod almindelige fejl. Den dag hvor jeg skal lave et program, hvor hukommelsesforbruget er en vigtig parameter, skal jeg nok lære det, men indtil da kan jeg finde andre ting at bruge tid på.

Jeg mener at man bør vælge det bedste værktøj til den opgave man har i hvert tilfælde. Fordi en boremaskine er dårlig til at slå søm i, betyder ikke at den er et dårligt værktøj.

Jarnis

PS. Den eneste gruppe programmører jeg kender, der virkelig optimerer deres kode idag, er virusprogrammører. Utroligt at man kan få en mailserver, et bagdørs-/fjernstyringsprogram, en beskedgenerator, en emailadresse-høster, mm. ned på under 20KB. En skam de ikke laver noget mindre destruktivt...

  • 0
  • 0
Anders Reinhardt Hansen

Den med at performance på java er dårlig er en urban myth, jvf. mit ovenstående indlæg om numeriske beregninger.
Men du har helt ret i at der går religion i det alt for tit. Jeg er en af dem der helst koder managed kode, C# og Java, og det er fordi at jeg mener jeg er mest produktiv her. Andre er mest produktive på andre platforme...
Det er godt der er mange slags is.

  • 0
  • 0
Morten Olsen

Jeg ville ikke kalde det en myte, men måske lettere forældet, for det var virkelig gældende det første lange stykke tid. Der gik laang tid før JVM'er med nogenlunde fornuftig jit kom frem. (vel omkring 2001? fra 1995). Og få mig slet ikke startet omkring Swing.. ;-)

Det er imponerende hvor godt de virtuelle maskiner klarer sig, men C koden i testen er unødvendigt forkrøblet, den kan blive hurtigere i alle test eksemplerne ved at bruge sse enheden istedet for stak fpu operationerne. (-mfpmath=sse -msse2, jeg testede det sidste gang der var en lignende tråd^h^h flamefest her). Java har rigtig mange fordele men man skal ikke misrepræsentere det, og rå performance på bit-sex kode er ikke en af de største :)

  • 0
  • 0
Anders Reinhardt Hansen

Du har helt ret med swing, det er ikke det bedste og hurtigste der findes, men java's forcer ligger også mest i enterprisemarkedet i mine øjne.
Ok, så meget er jeg ikke inde i c kode, som du åbenbart er, men det jeg vil sige er bemærkelsesværdigt er at java overhovedet er med heroppe! Det er måske ikke så brugbart, men det maner en hel del overtro i jorden. Jeg ville f.eks. gerne se rigtig meget mere java i opensource verdenen, jeg mener det passer fint sammen nemlig.

  • 0
  • 0
Dennis Krøger

"Et af problemerne med Java, var f.eks. at det var skrevet med bunker af processer. Nogle gange, kom éen process først. Andre gange, kom en anden process først. Måske var ikke de data, der skulle bruges, når processen blev udført - andre gange, var data der."

Det er ikke problemer med Java, det er problemer med en skodprogrammør der bruger multitrådet programmering uden at forstå hvad han arbejder med.

Den slags problemer har intet med sproget at gøre...

  • 0
  • 0
Jens Madsen

"Det er ikke problemer med Java, det er problemer med en skodprogrammør der bruger multitrådet programmering uden at forstå hvad han arbejder med.

Den slags problemer har intet med sproget at gøre..."

Du har både ret - og ikke ret. Der er nu altså sådant, at visse sprog, såsom Erlang, ikke fører til samme fejl som Java!

Hvordan kan det så være? Er det sådant, at en skodprogrmmør vælge Java, fremfor Erlang? Men, når selv samme programmører, har nemmere ved at få mangeprocessede ting til at fungere i Erlang, så må det jo være "noget" ved sproget!

Og netop det er pointen!

Ofte, er det faktisk sådant, at sprog fører til skodprogrammører. Naturligvis, kan du godt gøre det godt - og har du blot den mindste forståelse for multitrådet programmering, vil det ikke gå skidt. Men, har du et godt sprog, så "ledes" du til forståelse, fordi at dem der har udviklet sproget, havde forståelse. Hvor er vi, når dem der har udviklet sproget, ikke havde denne forståelse? Så er vi der, at skodprogrammører opstår. Sproget, er ikke godt.

Mit råd er derfor, at man studerer netop hvorfor, at nogle sprog har tendens til typer af fejl - meddens andre sprog ikke har samme tendens. De har måske andre problemer. Samtidigt, bør man, når man udvikler et sprog, netop forsøge at undgå, at dem der bruger sproget, skal være dygtige, lære en masse, og derved sikre at de kun skriver godt kode. Alt erfarring viser nemligt, at denne ideologi ikke fungerer. Er muligheden for dårlig kode, vil den altid blive brugt. Derfor, er det sprogets opgave, at kunne sikre at programmørerne koder godt.

Der kan opsættes regler for, hvad et sprog må kunne, og hvordan den skal fungere, for at et multitrådet program fungerer, og fungerer deterministisk. Der kan direkte udpeges specifikt, hvor der kan være problemer, når sproget begrænses til dette, og hvordan disse løses. Løsningerne, kan være en del af sproget, så det normalt ikke fejler. Og er der nogen "tvivl" om at her kan opstå fejl, kan man gøre det synligt for programmøren, ved at dels forhindre det kan gøres uden ekstra sikkerhed, og man kan lave sproget, så man som programmør har mulighed for en tjek i compileren/fortolkeren, der sikrer at de rutiner som bruges, faktisk er deterministiske. Det er vigtigt, at man kan sætte krav til determinismen i mange funktioner, og forhindre at en evt. programmør af en black-box, ikke opfylder et sådant krav.

Programmeringssprog, er i høj grad årsag til begreber som skodprogrammering. Og man kunne - lidt våvet påstå - at det måske var sproget, der var et skodsprog. Jeg påstulerer ikke, at det er muligt at lave programmeringssprog, så software altid vil fungere 100%, og at det er umuligt at lave noget der ikke dur. Men, der kan gøres meget - og det er muligt, at både opnå hurtigere svartid, nemmere programmering (det tror jeg java programmørern har erfarret), og større sikkerhed.

De fleste ved det godt. Deres erfarring siger dem, at det er "nemmere" med Java, end C++. Men, ingen ved måske helt hvorfor. Min påstand er, at man kan gå endnu videre ud af den tangent. Og gøre det bedre, end Java - og C++. Java er ikke optimalt. Men, man virker som dum, hvis man først opdager det, den dag at der kommer et nyt sprog - trods man måske er først til at hoppe fra vognen, og over på det nye sprog.

Sprog skal overvejes grundigt, af dem der laver dem. De fleste sprog, er udviklet for hurtigt. Og samme med operativsystemer. Dette gør det sværre at programmere, og den ekstra tid der kunne have været brugt på forskning og udvikling af sprog, samt programmering af compileren vil være godt tjent ind, i forhold til alle de millioner programmører som findes. I dag findes mange millioner Java programmører. De burde alle brokke sig hvis de kunne se, at noget kunne gøres bedre, for det er uacceptabelt, at man ikke gør tingene godt nok, til at ingen kan finde noget bedre. Naturligvis er det også lidt subjektivt. Men, der er store tendenser.

Det er også vigtigt, at operativsystemer, og programmeringssprog, laver de vigtige optimeringer. Noget som Cache, er ikke noget der skal kodes, i et programmeringssprog. Operativsystemet tager sig af cache. Uanset, du bruger filer, eller ram, så er det operativsystemets opgave, at gøre det ordentligt. Hvis den ikke gør det, vil du kunne "tvinges" til at selv kode noget cache styring, og derved besværliggør det dit arbejde, og din kodning. Samtidigt, opnås løsningen ikke genneralt, som hvis den var del af operativsystemet.

I nogle få tilfælde, kan man dog forvente, at man hjælper lidt, med at styre operativsystemets cache korrekt, ved f.eks. at have en ordre der ikke tager tid, og som kan fortælle hvad der bliver brug for fremover. Eller, man kan lave en anden task, man sender dette til, som så søger at bruge det (uden at bruge det reelt), kun for at sikre data er tilstede. Også her, vil vi gerne have, at operativsystemet, og compileren, er i stand til at spå. For et godt sprog, tror jeg faktisk vi kan komme op med en algorithme der gør det selv, så computeren altid finder dataene i god tid. Jeg læste at nogle forskere i Århus, arbejder på et sådant problem - og det lyder fornuftigt. I nogle tilfælde, vil det kunne gøre computeren tusind gange hurtigere.

Ovenstående, skulle gerne være med til at illustrere, at jo dygtigere de er, dem der udvikler sprogene, jo bedre skulle koden gerne blive. Og mulighederne for faldgrupper mindre. Jo bedre, at dem der udvikler sprog, compilere, og operativsystemer er til optimering - jo mindre behøver du at tænke på optimering, når du kode. Du skal ikke kode cache, eller tænke på, at du måske i fremtiden får brug for noget - metoderne opdager det. Og sikrer, at det hentes i god tid, før du bruger det. Pauser, fordi det ikke er hentet, bruges også fornuftigt, og det er sat op via operativsystem, således det virker som om at computeren svarer hurtigt, og ikke har forsinkelse. Det er ikke "bare" at bruge en pause, til noget "tilfældigt", eller til et program der måske har størst prioritet. Problemet er langt mere kompleks.

Mit problem med Java, er ikke at det på nogle områder er, at det er blevet bedre end C++. Problemet er, at jeg ikke mener, det er godt nok. Jeg vil have, at man tænker sig ordentligt om, og det skal gå hurtigt. For vi gidder ikke, at kode i sprog, og alt skal gøres mere besværligt end muligt. Så er bedre, at sætte enorme og kæmpe resourcer ind, på at udvikle og forske i nye operativssystemer og nye programmeringssprog. Sprog, som gør arbejdet nemmere til noget fungerer, og minimerer mulighed for fejl.

Vi skal gerne opnå, at software fungerer. I dag, er der intet som dur...

  • 0
  • 0
Dennis Krøger

"Du har både ret - og ikke ret. Der er nu altså sådant, at visse sprog, såsom Erlang, ikke fører til samme fejl som Java!

Hvordan kan det så være? Er det sådant, at en skodprogrmmør vælge Java, fremfor Erlang? Men, når selv samme programmører, har nemmere ved at få mangeprocessede ting til at fungere i Erlang, så må det jo være "noget" ved sproget!"

A. Jeg gider ikke læse dit kilometer indlæg til ende.

B. At en lille gruppe sprog er skrevet specielt til formålet (eller hvor det kommer som en naturlig del af den type sprog), ændrer ikke på at det ikke havde noget med sproget at gøre i dit oprindelige indlæg, det var bare dig der fortsatte ud af endnu en ligegyldig tangent i din anti-Java crusade.

De fleste af dine indlæg handler om hvor meget nemmere det hele kunne gøres, og hvor elendig det hele er nu (OG hvor nemt det ville være at ændre på, "man skal bare liiiige..."). SÅ KOM DOG FOR "#¤%/&¤¤&% IGANG ISTEDET FOR AT SIDDE OG BRALRE VILDE TEORIER AF!

...Kan vi ikke nok give Anne-Sofie sin tråd tilbage nu, hvis altså ikke det oprindelige emne er ødelagt fuldstændigt, af tåbelige off-topic indlæg (jeg undskylder for min del af dem...)?

  • 0
  • 0
Jens Madsen

"det var bare dig der fortsatte ud af endnu en ligegyldig tangent i din anti-Java crusade."

Det er misforstået. Det er absolut ikke anti-Java, tværtimod. Java nærmest beviser, at det kunne gøres bedre end det tidligere eksisterende - såsom C++. Det er et "mere-Java" crusade, altså at vi ønsker MERE ud af den tangent. Det er et spændende område, og jeg håber at flere vil interessere sig for området, og måske være forskere.

Jeg undskylder også for mine off-topic indlæg - og vi bør gå tilbage til det oprindelige problem. Findes memory leaks i Java, hvis der ikke er fejl i bilblioteker, og hvis vi husker at frigive vores pointere, så der ikke er adgang til data på nogen måde?

  • 0
  • 0
Jens Madsen

I tilfældet, at ingen mener det er muligt med memory leaks i Java - andet end dem programmøren laver ved at der stadigt er adgang til data - kunne man måske uden at gå for langt bort fra topic, spørge om Java "opfordrer" til memory leaks, og fungerer på en måde så programmørerne ikke opdager, de ikke har "frigivet" data? Det er jo som sådant også sprogets fejl.

  • 0
  • 0
Dennis Krøger

"kunne man måske uden at gå for langt bort fra topic, spørge om Java "opfordrer" til memory leaks, og fungerer på en måde så programmørerne ikke opdager, de ikke har "frigivet" data?"

Hmmm, at nogle ikke tænker over at de har referencer til objekter liggende og flyde uden at have brug for dem, kan man nok ikke gøre så meget ved, uden en større gang analyse (f.eks. som Anne-Sofie brugte, en profiler). Man kunne argumentere for at interpreteren/compileren lavede ekstra analyse ("Har du virkelig brug for den som klassevariabel, du bruger den jo kun en gang?"), men alt hvad man kaster ind, koster.

Jeg tror det er smartest med et bevidst valg at undersøge den slags, når man finder ud af at ens program er større end det burde være. Men det kan da være at den slags kunne være en fordel, hvis det er "billigt" nok (I compiletid og mængden af unødige warnings).

  • 0
  • 0
Bob Hagenstrup

Hmm, det kommer vel ogsaa an paa hvad man kalder memory leaks...

F.eks. er det saa vidt jeg ved meget nemt at lave memory leaks hvis man bruger biblioteket SWT ( http://www.eclipse.org/swt/ ) da det afhänger af bindings til eksterne libs, og derfor kräver at man dräber sine objekter, hvilket man saa vidt jeg ved ikke skal hvis man bruger en af de indbyggede grafik biblioteker til Java (AWT, Swing).

(jeg er ikke java mand saa bash mig ikke)

  • 0
  • 0
Log ind eller Opret konto for at kommentere