Gå til hovedindhold
Version2 it for professionelle
Forsiden

Hovedmenu

  • It-nyheder
  • Blogs
  • It-job
  • It-firmaer
  • Whitepapers
  • Opret bruger
  • Log ind
Du kan logge ind med din e-mail-adresse
Der er forskel på store og små bogstaver i adgangskoden.
Glemt adgangskode?
Se kommentarer (4)
Emner .Net, C#, Windows Phone 7

Windows Phone Performance og billeder

Af Martin Esmann 10. juli 2012 kl. 12:04

Jeg har nu arbejdet med Windows Phone i lang tid og i den forbindelse fået en hel del erfaring med performance på Windows Phone… så jeg tænkte at jeg ville dele lidt erfaring med, dem af jer som til hverdag eller på hobby plan udvikler til Windows Phone.

I de fleste tilfælde er det faktisk super nemt at lave en app til Windows Phone, selvfølgelig meget afhængigt af ambitionsniveauet, men generelt set er det ikke så svært. Der er god hjælp fra Visual Studio + Blend og SDK’et er godt dokumenteret … og så er det masser af eksempler fra andre udviklere. Et sted hvor dokumentationen er relativt ”stille” er ang. Billeder og hvordan billeder håndteres på Windows Phone. Der er nemlig noget så smart som en ”image bufferen” som skal sikre hurtig load af billeder fra hukommelsen… dokumentationen glemmer bare at nævne at ”image bufferen” ikke har en øvre grænse, den kan blive uendelig stor, altså i moderne tale har vi et potentielt ”memory leak” medmindre vi tænker os godt om som udviklere. Hvis vi, som udviklere, ikke gør noget aktivt fjernes billederne nemlig ikke fra hukommelsen før appen lukker ned og det er et STORT problem hvis vi fx vil håndtere mange billeder.

Så hvordan laver man en WP app. som kan vise 1 million billeder? En Windows Phone app må på intet tidspunkt bruge mere end 90 MB hukommelse og skal helst holde sig under 70 MB. En helt tom applikation fylder ca. 8MB i hukommelsen: ca. 4.5MB til .NET Runtime det resterende bruges til UI’et pagen og tilhørende kontroller etc. Det betyder at man rundt regnet har 60 MB hukommelse til at holde de 1 million billeder og tilhørende UI. Vi kan derfor hurtigt konkludere at alle billederne ikke kan være i hukommelsen på én gang… de skal loades dynamisk.

Dynamisk generering (Virtualizing i Windows Phone termer) er derfor den eneste udvej. For eksemplets skyld bruger vi en ”ListBox” control til at vise billederne. I praksis er det komplet urealistisk at skulle lave en ”scroll” gennem så mange billeder, men denne løsning er perfekt til at teste performance. Sm standard loader en ListBox alt sit indhold, altså i dette tilfælde vil ListBox kontrollen forsøge at hente alle billederne og gemme dem i hukommelsen for at give den bedste scroll oplevelse. Selvsagt en dårlig ide. Denne standard opførsel kan dog hurtig ændres ved at ændre ItemTemplate på ListBox’en til et VirtualizingStackpanel, således:

<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="MainListBox_SelectionChanged">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                      <StackPanel Margin="0,0,0,17" Height="400">
                            <Image Source="{Binding LineOne}"/>
                            <!--<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                          <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>-->
                      </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

En hurtig test viser også ganske rigtigt at denne løsning er ganske effektiv og rent faktisk er i stand til at vise de mange billeder uden at bryde sammen. Men tester man lidt grundigere og laver en serie af hurtige ”scroll” og navigere en smule ”aggressivt” ser man hurtigt at dette ikke er en god nok løsning. Altså så længe vi har nogle rolige og afslappede bruger skal det nok gå, men hurtige bevægelser betyder at hukommelsen hurtigt kommer over 90MB grænsen. Hvis man er lidt fingernem på musen kan man i emulatorer komme op på mere end 200MB. Det er ikke de 200MB, i sig selv, der er interessante, det er det faktum at de aldrig bliver fjernet af GC’en. Altså vi har et memory leak på 200MB… se selv herunder og test meget gerne selv :)

(Bemærk de røde tal i højre margin, de skulle aldrig kommer op over 90)

Et eller andet sted i vores app er der et memory leak… men hvor og hvordan løser vi det? Efter en del research på nettet og gennem egne tests ser det ud til at problemet opstår fordi billederne hentes ”dynamisk” fra nettet. Det der tilsyneladende sker er at ListBox’en forespørg et billedelement, men inden billedet er hentet og klar til at blive vist for brugeren så har brugeren ”scroll’et” forbi og vores ”item container i ListBox” er blevet fjernet. Det betyder at billedelementet ikke længere et bundet til et ListItem… men så at sige hænger frit i hukommelsen. GC’en kan derfor ikke finde frem til og fjerne billedelementet. Deraf vores memory leak.

Jeg har forsøgt mig med rigtig mange løsninger og mange af dem har været ret kreative og omhandlet annullering af downlaod etc. Problemet kan dog tilsyneladende altid fremprovokeres så længe vi har en asynkron operation. Alt i Windows Phone er pr design asynkront, med undtagelse af IsolatedStorage (app filsystemet på Windows Phone).

Den eneste gyldige løsning jeg har kunne lave har derfor været at downloade billederne til IsolatedStorage og efterfølgende hente dem synkront til UI’et. Det er dog ikke helt så simplet som det lyder, så jeg vil foreslå at du selv kigger koden igennem … det ender med at være rigtig mange kodeliner.

Hvis du stresser appen kan den godt komme op på nogle af 80MB, den skulle dog gerne falde ned igen hurtigt.

Brug gerne koden i dine egen 1 million billeder app :)

Hent koden her: Source

PS. Jeg har ikke testet koden med 1million billeder, det er min tålmodighed simpelthen ikke til ;)

Send Tweet
Udskriv
Billede af Martin EsmannOm Martin Esmann

Martin arbejder i Microsoft med udvikling af apps til Windows Phone og Windows 8, samt har ansvaret for den tekniske relation til universiteterne i Danmark. Han blogger fortrinsvis om apps udvikling til Windows platformen.

Follow @martinesmann

Kommentarer (4)

Opret en konto eller log ind for at følge indhold på Version2 - og bliv opdateret via e-mail eller rss

Følg kommentarer
Daniel Madsen 10. jul. 2012 - 13.32
 
..
Det betyder at billedelementet ikke længere et bundet til et ListItem… men så at sige hænger frit i hukommelsen. GC’en kan derfor ikke finde frem til og fjerne billedelementet. Deraf vores memory leak.

Det burde nu ikke være problemet, GC'ens opgave er netop at finalize objekter der så at sige "hænger frit i hukommelsen". Problemet er snarere at du stadig har referencer til disse objekter, omend de ikke nødvendigvis er så åbenlyse (f.eks. delegates eller event binding kan nogle gange holde referencer) - dette forhindrer GC'en i at frigive objekterne.

Billedobjekter især har normalt referencer til native resources og det er derfor vigtigt at du explicit kalder Dispose() på disse når du er færdig med at bruge dem.

Og btw. så er aggressiv brug af GC.Collect() normalt et symptom på "you're doing it wrong" snarere end løsningen :-)

Jeg synes iøvrigt det virker lidt mærkeligt at poste halvfærdig / fejlbehæftet kode her på blogging - for mig at se hører debugging måske snarere hjemme på StackOverflow? :)

  • Stem op 10
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Martin Esmanns billede
Martin Esmann 11. jul. 2012 - 08.28
 
Re: ..

Helt enig, det burde ikke være nødvendigt at køre GC'en selv... men prøv at køre sample appen. Så længe alt gøres langsomt og roligt er der ingen problemer, men er man for hurtig så kommer problemet.

Jeps, events og delegates kan give en del udfordringer, men i dette tilfælde er det altså ikke kode jeg selv har skrevet det er "drag & drop" koden som giver udfordringen og ikke slipper alle referencer... derfor er jeg nød til selv at kode det hele op.

Billedobjekter... igen i drag & drop koden kan jeg ikke manuelt kalde dispose... det skulle gerne initieres af Virtualizing delen... og det går fint så længe alt gøres langsomt. Stress udløser fejlen.

enig, manuel brug af GC er oftest ikke et godt tegn :) Men GC køre anderledes på WP end desktop og derfor kan det i nogle tilfælde være bedre at køre GC end at kommer mem. limiet... eller ;)

Stackoverflow er tiltænkt tekniske spørgsmål ikke nødvendigvis "sample" kode som denne.

Hvad mener du med at jeg ikke bør poste halvfærdig kode?! Viser koden ikke min pointe tilstrækkeligt?

  • Stem op 2
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Martin Esmanns billede
Martin Esmann 11. jul. 2012 - 08.33
 
Re: ..

... og så glemte jeg lige en lille ting. Når jeg laver en memory profiling af appen ser det ud til at "de frie" billedelementer bindes til app'en og derfor først fjernes når appen lukker helt ned. Det er lidt svært at se præcis om det korrekt jeg kan blot konstatere at jeg har en masse "Visuals" som ikke bliver fjernet.

  • Stem op 1
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer
Morten Jensen 13. jul. 2012 - 01.54
 
Re: 1 mio billeder
PS. Jeg har ikke testet koden med 1million billeder, det er min tålmodighed simpelthen ikke til ;)

Hahahah jeg havde besluttet mig for at spørge dig hvordan du havde testet 1 mio billeder, og om hvordan filsystemet håndterede det - lige indtil jeg læste din sidste linie :)

Jeg udvikler normalt mod *nix og/eller embeddede targets, men jeg synes din artikel er spændende. Jeg synes det er HELT i orden at poste kode der ikke er færdigt. Det er meget bedre end at gemme på sit hyggeprojekt fordi man er bange for folks gransken.

  • Stem op 1
  • Stem ned 0
  • anmeld
  • Log ind eller opret en konto for at skrive kommentarer

Tilføj kommentar

Opret en konto eller log ind for at følge indhold på Version2 - og bliv opdateret via e-mail eller rss

Følg kommentarer
Log ind herunder eller opret en bruger for at skrive kommentarer
Du kan logge ind med din e-mail-adresse
Der er forskel på store og små bogstaver i adgangskoden.
Glemt adgangskode?

Seneste nyt

Samsung på vej med lynhurtig mini-SSD med PCIe-forbindelse

Udgivet 19. jun 15.31Opdateret 19. jun 15.31

Amazon bygger privat sky til CIA for 3,3 milliarder kroner

Udgivet 19. jun 14.47Opdateret 19. jun 14.47

Trine Bramsen: Handicapfilm er skræmmekampagne

Udgivet 19. jun 14.02Opdateret 19. jun 14.02

Microsoft kaster Surface RT i grams til studerende for 1.100 kroner

Udgivet 19. jun 13.08Opdateret 19. jun 14.39

Umuligt at spærre for: Her er afløseren for tracking med cookies

Udgivet 19. jun 11.51Opdateret 19. jun 11.51

Flere it-nyheder »

Tilmeld dig Version2's it-nyhedsbrev og vind en iPad mini.

Seneste debat

  1. Softwarepatent-modstander: Gør dine venner og familie klar til folkeafstemning

    17 comments.
    Last update 3 minutter 15 sekunder
    Skrevet af Niels Didriksen
  2. Umuligt at spærre for: Her er afløseren for tracking med cookies

    7 comments.
    Last update 12 minutter 32 sekunder
    Skrevet af Peter Hansen
  3. NSA bagdøre i Open Source ?

    80 comments.
    Last update 25 minutter 55 sekunder
    Skrevet af Jan Poulsen
  4. Udviklere finder hul i DSB 1: Kommer gratis på nettet

    18 comments.
    Last update 42 minutter 39 sekunder
    Skrevet af Søren Mors
  5. Amazon bygger privat sky til CIA for 3,3 milliarder kroner

    1 comment.
    Last update 50 minutter 4 sekunder
    Skrevet af Lars K. Hansen
  6. Mogens Nørgaard fyret fra Miracle

    19 comments.
    Last update 50 minutter 53 sekunder
    Skrevet af Mogens Nørgaard
  7. Microsoft kaster Surface RT i grams til studerende for 1.100 kroner

    1 comment.
    Last update 51 minutter 4 sekunder
    Skrevet af Peter Sørensen
  8. Trine Bramsen: Handicapfilm er skræmmekampagne

    1 comment.
    Last update 1 time 5 minutter
    Skrevet af Jens Beltofte Sørensen

Mere debat »

It-virksomheder

Eksponent
|
Strongminds At Work
|
Bring IT
|
Financys
|
Codecompany.DK
|
C-Tilsted
|
Netlinq
|
Hedal Kruse Brohus
|
Structura - IT
|
Abusiness
|
Data-Force
|
Valeo
 

Information

  • Kontakt redaktionen
  • Job- og annoncesalg
  • Teknisk support
  • Om Version2
  • Brugerbetingelser
  • Cookie- & privatlivspolitik

Aktuelle emner

  • Business Intelligence
  • CSC-hacking
  • Cloud computing
  • Intranet
  • It-sikkerhed
  • NSA Prism
  • NemID
  • Open source CMS
  • Projektledelse
  • Scrum
  • Storage
  • Virtualisering
  • Windows 8
  • iOS 7

Tjenester

  • iPhone-app
  • RSS-feeds
Følg @version2dk
Tilmeld dig Version2's it-nyhedsbrev og vind en iPad mini.

Version2 udgives af

  • Mediehuset Ingeniøren A/S work Trekronergade 26 2500 Valby
  • Tlf. work 33265300