Fetstil Fetstil Kursiv Understrykning linje färgläggning tabellverk Punktlista Nummerlista Vänster Centrerat högerställt Utfyllt Länk Bild htmlmode
  • Forum & Blog
    • Forum - översikt
      • .Net
        • asp.net generellt
        • c#
        • vb.net
        • f#
        • silverlight
        • microsoft surface
        • visual studio .net
      • databaser
        • sql-server
        • databaser
        • access
        • mysql
      • mjukvara klient
        • datorer och komponenter
        • nätverk, lan/wan
        • operativsystem
        • programvaror
        • säkerhet, inställningar
        • windows server
        • allmänt
        • crystal reports
        • exchange/outlook
        • microsoft office
      • mjukvara server
        • active directory
        • biztalk
        • exchange
        • linux
        • sharepoint
        • webbservers
        • sql server
      • appar (win/mobil)
      • programspråk
        • c++
        • delphi
        • java
        • quick basic
        • visual basic
      • scripting
        • asp 3.0
        • flash actionscript
        • html css
        • javascript
        • php
        • regular expresssion
        • xml
      • spel och grafik
        • DirectX
        • Spel och grafik
      • ledning
        • Arkitektur
        • Systemutveckling
        • krav och test
        • projektledning
        • ledningsfrågor
      • vb-sektioner
        • activeX
        • windows api
        • elektronik
        • internet
        • komponenter
        • nätverk
        • operativsystem
      • övriga forum
        • arbete karriär
        • erbjuda uppdrag och tjänster
        • juridiska frågor
        • köp och sälj
        • matematik och fysik
        • intern information
        • skrivklåda
        • webb-operatörer
    • Posta inlägg i forumet
    • Chatta med andra
  • Konto
    • Medlemssida
    • Byta lösenord
    • Bli bonsumedlem
    • iMail
  • Material
    • Tips & tricks
    • Artiklar
    • Programarkiv
  • JOBB
  • Student
    • Studentlicenser
  • KONTAKT
    • Om pellesoft
    • Grundare
    • Kontakta oss
    • Annonsering
    • Partners
    • Felanmälan
  • Logga in

Hem / / start / krönika / Hur står det till med minnet - Del 1? Standard

Hur står det till med minnet - Del 1?

Av: Andreas Håkansson
Publicerad: 2004-04-27

Med lanseringen av .NET introducerade Microsoft en beprövad metod för minneshantering, Garbage Collection. I grova drag innebär det att Du oftast inte behöver oroa dig över att reservera och frigöra minne som du behöver, då det sker per automatik. Trots det är det viktigt att du, som utvecklare, har förståelse för hur minneshanteringen fungerar då det kan påverka så väl ditt sätt att skriva program, som externa resurser.


Grunderna för minneshantering

Då minneshantering är ett område som det bedrivs mycket forskning på för att optimera användningen av minnet har det genom tiderna funnits en rad olika lösningar som ansetts vara den mest effektiva.

Under åren som har gått har man gjort fler och fler framsteg inom optimeringen men de underliggande principerna för minneshantering har varit de samma:

  • Reservera minnet
  • Initiera minnet
  • Använd minnet
  • Riva ner minnet
  • Frigöra minnet

De tillsynes enkla stegen har varit källan till många problem inom programutveckling. Ett vanligt problem är att man försöker använda minne man inte ännu reserverat eller som man redan har frigjort.

Vad som skiljer olika utvecklingsmiljöer åt är hur de har valt att hantera de olika stegen, samt till vilken grad du som utvecklare är involverad.

Minneshantering i .NET Framework

Microsoft valde att utveckla en stack-baserad miljö när de skapade .NET Framework. Det innebär att den kod som skall exekveras läggs på en stack1 och hämtas ut vid själva exekveringen.

Förenklat kan man säga att varje rad kod som .NET exekvera hamnar som en egen post på stacken, vilket innebär det minne som en variabel använder sig av frigörs automatiskt när posten som den använder plockas ut från stacken.

Varje exekverande tråd tilldelas en egen stack vilket gör att man inte har direkt åtkomst av variabler mellan olika trådar.

Denna typ av minneshantering är en sanning med en viss modifikation, då Microsoft även har delat upp variabler i två kategorier:

  • Värdetyper (Value types)
  • Referenstyper (Reference types)

Det är viktigt att du som utvecklare förstår skillnaden mellan de två typerna då de har stor inverkan på hur minneshanteringen i .NET fungerar.

En värdetyp skapas direkt på stacken och innehåller sitt eget värde. Hit tillhör variabler av typer så som int, bool, enum och struct.

Referenstyper skapas också på stacken men med en skillnad; de innehåller inte sitt eget värde direkt på stacken, utan lagrar istället en pekare till något som kallas en heap. En referenstyp är t.ex. en klass, en vektor eller en sträng.

Vad är en heap?

Varje gång en ny process startas så reserverar .NET en kontinuerlig följd av minne som tilldelas processen. Det är denna följd av minne som kallas för en heap och den används i .NET för att lagra den information som en referenstyp använder.

I .NET använder sig heapen av en pekare för att göra en insättning av nya objekt. När heapen skapas pekar denna pekare på den första minnesadressen som heapen använder sig av.

När ett nytt objekt skall placeras på heapen stoppas det in på pekarens adress sedan flyttas så att den befinner sig på adressen precis efter objektet.
Valet att använda en pekare gör att insättning av nya objekt blir väldigt snabb då den enbart behöver flyttas till en ny minnesadress för att kunna sätta in nästa objekt.

Garbage Collection (GC)

Det ställs väldigt högra krav på minneshantering eftersom det är en central del i exekveringen av alla applikationer.

Automatiserad minneshantering kräver att vissa av de relevanta aspekterna fungerar på ett optimalt sätt för att inte få negativ inverkan på exekvering:

  • Val av objekt att frigöra
  • Tidpunkt för minneshantering
  • Korrekt nedbrytning av objekten
  • Prestanda vid minneshantering

Microsoft har givetvis implementerat de lösningar som de anser sig vara bäst för .NET-plattformen, samt bedriver kontinuerlig forskning för att kunna förbättra dem ytterligare.

Val av objekt att frigöra

Det har funnits många lösningar på hur man skall avgöra om ett objekt kan frigöras eller inte. Några av de metoder som använts är att låta utvecklaren ansvara för frigöring av minne eller att använda sig av så kallad referensräkning. 

 

Båda metoderna har fördelar och brister som ligger utanför det som denna artikel behandlar. Givetvis är det så att bristerna är fler än fördelarna, annars skulle inte Microsoft ha valt att implementera en annan form av minneshantering.

För att kunna avgöra om ett objekt kan frigöras så måste .NET kunna kontrollera om det används av någon.

GC:n avgör om ett objekt kan frigöras eller inte genom att undersöka applikationsrötterna. Varje applikation tilldelas en uppsättning rötter när det startas.

Applikationsrötterna består av globala och statiska referenser till objekt, lokala variabler, referensparametrar och CPU-register och kan antingen peka till ett objekt på heapen eller ha ett null-värde.

De objekt på heapen som kan nås med hjälp av en rot kommer inte att betraktas som en kandidat för frigöring när minneshantering sker.

Tidpunkt för minneshantering

En viktig aspekt för automatisk minneshantering är att kunna avgöra när det skall ske. Om hanteringen sker för ofta riskerar man att försämra programmets prestanda och om det sker för sällan ökar risken för att det använda minnet skall växa.

För er läsare med kunskaper om hur minneshantering i ett operativsystem fungerar så känner ni till att ökad minneanvändning av ett program kan leda till fler sidallokeringsfel. Det kan i sin tur leda till försämrad prestanda för samtliga processer som exekveras då virtuellt minne måste användas i allt högre grad.

Det finns flera faktorer som avgör när .NET skall aktivera GC:n. Den mest grundläggande är den optimeringsmotor som Microsoft har byggt in i .NET och som använder sig av en algoritm för att övervaka minnesanvändningen.

Kriterierna för denna algoritm är inte offentliga då det är en av hemligheterna i deras implementation.
En vanlig orsak till att GC:n aktiveras är när ett program anropar new för att skapa ett nytt objekt på heapen. Om det inte finns tillräckligt med tillgängligt minne för att lagra det nya objektet så kommer ett så kallat OutOfMemoryException fel att kastas vilket får .NET att aktivera GC:n.

Som utvecklare har du även möjlighet att själv anropa GC:n och be den frigöra minne från heapen. Det är oftast inte rekommenderat att du utnyttjar denna möjlighet om du inte har väldigt god anledning.

Orsaken till detta är att du troligen inte kan fatta ett bättre beslut än vad optimeringsmotorn själv gör, vilket kommer leda till försämrad prestanda av din applikation.

När GC:n aktiveras så upphör alla trådar i en applikation att exekvera, vilket är anledningen till att man inte vill att minneshantering skall ske så fort ett objekt skulle kunna frigöras.

Frigöringsalgoritm

Microsoft valde att implementera GC som genomför sitt arbete i en tvåstegsprocess, en så kallas ”Mark and Sweap” algoritm. Den utgångspunkt man använder sig av är att allt som finns på heapen kan frigöras om det inte kan motbevisas.

Första steget kontrollerar om det finns några aktiva referenser mellan objekten och applikationen genom att vandra längs med applikationens rötter. Vid detta tillfälle kontrolleras även indirekta referenser för de objekt som det finns en aktiv referens till.

En indirekt referens är en referens till ett objekt som enbart kan nås från ett objekt som är tillgängligt från en av rötterna.

Vid andra steget påbörjar GC:n sitt arbeta med att frigöra de objekt som det direkt, eller indirekt, inte kunde hittas någon referens till.

Efter det att objekten har frigjorts kommer det att finnas luckor mellan de kvarvarande objekten. För att öka effektiviteten av minnesanvändningen packas de objekt som finns kvar ihop till en kontinuerlig följd.
Att organisera om objekten så att de ligger placerade i en kontinuerlig följd innebär att alla referenser, som GC:n tidigare hittade, måste pekas om till de nya minnesadresserna.

När de två stegen är avslutade har minne frigjorts och GC:n lämnar tillbaka exekveringen till applikationens trådar.

Sammanfattning

Detta har varit en övergripande introduktion till den minneshantering som .NET Framework använder. Jag kommer vid nästa tillfälle att börja titta in på lite mer komplicerade delar av GC:n och dess funktionalitet.

Diskutera krönikan här »


1En stack är en datastruktur där information läses i omvänd ordning som den skrevs.

Nyligen

  • 08:28 Butiksskyltar: Hur upplever utbude
  • 22:31 Slappna av
  • 19:55 kick-off med fokus på hälsa?
  • 19:53 kick-off med fokus på hälsa?
  • 16:24 Föreslå en skönhetsklinik online
  • 16:23 Föreslå en skönhetsklinik online
  • 18:42 Hvor finder man håndlavede lamper
  • 18:41 Hvor finder man håndlavede lamper

Sidor

  • Hem
  • Bli bonusmedlem
  • Läs artiklar
  • Chatta med andra
  • Sök och erbjud jobb
  • Kontakta oss
  • Studentlicenser
  • Skriv en artikel

Statistik

Antal besökare:
Antal medlemmar:
Antal inlägg:
Online:
På chatten:
4 570 831
27 960
271 761
3 049
0

Kontakta oss

Frågor runt konsultation, rådgivning, uppdrag, rekrytering, annonsering och övriga ärenden. Ring: 0730-88 22 24 | pelle@pellesoft.se

© 1986-2013 PelleSoft AB. Last Build 4.1.7169.18070 (2019-08-18 10:02:21) 4.0.30319.42000
  • Om
  • Kontakta
  • Regler
  • Cookies