windows - C # simple app skabe enorme antal i sidefejl. Hvorfor?

Indlæg af Hanne Mølgaard Plasc

Problem



Har en simpel C # konsol app, der importerer tekstdata til SQL.


Det tager omkring 300K i hukommelse og 80\% i CPU. Der er 2GB RAM til rådighed til enhver tid, og siden viser sidefejl 500K.


App'en er 32 bit og OS er enten W2000 eller XP 32 bit og .NET 3.5


Enhver kan forklare, hvad der kunne være problemet, og hvordan kan jeg undersøge dette yderligere?


EDIT: Jeg er nu sikker på, at sidefejlene er relateret til disken I/O (læs). Jeg kommenterede SQL-del og den rene disklæser genererer det høje tal alene.


EDIT2: Der er 200 hardfejl/sek og 4000 bløde fejl/sek i gennemsnit.


Jeg spekulerer på, om det samme ville ses på W2008

Bedste reference


Først hvordan måler du den hukommelse, appen bruger? Hvis du ser på 'arbejdssæt', er det kun den del, der ligger i fysisk hukommelse. Du bør også kigge på 'VM Size' (eller 'Commit Size'), hvor den faktiske virtuelle hukommelse din proces tager op.


Hvis Windows-kerne Balance Set Manager mener, at din app er inaktiv eller skal efterlades for at give andre processer mere strøm, kan det beslutte at reducere størrelsen på arbejdssæt. Hvis arbejdsindstillingsstørrelsen er mindre end hvad din ansøgning rent faktisk skal arbejde på, kan du nemt se mange sidefejl, fordi det blot bliver et løb mellem Balance Set Manager og applikationen. Normalt overvåger saldobaseret manager hukommelsesforbruget og kan også beslutte at øge arbejdsstørrelsen i overensstemmelse hermed. Dette kan dog forhindres under visse omstændigheder som lav fysisk ledig hukommelse, høj I/O (cache stress på fysisk hukommelse), lav proces priorty, ansøgningens baggrund/forgrundsstatus osv.


Det kan simpelthen være opførelsen af. NET affaldssamleren på grund af en lang række små hukommelsesblokke, der bliver tildelt og afsat på meget kort tid, hvilket forårsager stress på både hukommelsesallokering og frigivelse. 'VM-størrelsen' kunne forblive omkring samme størrelse, men bag kulisserne kunne det løbende allokere/frigøre hukommelse, hvilket forårsager kontinuerlige sidefejl.


Ved også, at DLL'erne, som processen bruger, også står for processtatistikken. Ikke din app, men en af ​​de COM eller. NET DLL'er du bruger, kan også forårsage denne adfærd. Du kan udlede den faktiske skyldige ved at ændre din applikations adfærd (f.eks. Fjernelse af DB adgangskode og kun forlade objektallokeringskoden bagved) for at se, hvilken komponent der faktisk forårsager thrashing.


EDIT: Om dit spørgsmål om GC-indvirkning på hukommelsestråling: CLR'en vokser faktisk højden dynamisk og giver hukommelsen tilbage til operativsystemet efter behov. Det sker ikke synkront. GC kører bag kulisserne og frigør hukommelse i store klumper for at forhindre, at applikationsydelsen forringes. Sig, at du tildeler mange små genstande og frigør dem næsten med det samme. Det forårsager mange henvisninger til at forblive et øjeblik i hukommelsen, før de frigives. Det er nemt at forestille sig, at det bliver som et head-to-head løb mellem affaldssamleren og hukommelsesallokeringskoden. Mens GC i sidste ende fanger op, skal den nødvendige nye hukommelse være tilfredsstillet fra en 'ny hukommelse', ikke den gamle, fordi den gamle ikke er frigjort endnu. Da den egentlige hukommelse vi arbejder på, forbliver omkring det samme, kan balanceindstillingsprogrammet måske ikke tænke på at give vores proces mere hukommelse, fordi vi er på kanten, altid omkring den samme fysiske hukommelsesstørrelse, men konstant brug for 'nyligt tildelt hukommelse' ikke 'mere' mere hukommelse ', derfor sidefejl. [1]

Andre referencer 1


Sidefejl er normalt. Hukommelsen bliver byttet ud, og når du får adgang til det, er der en sidefejl, og systemet bringer det tilbage. Dette er ved design.


Jeg har en app, der kører på min maskine lige nu med 500 millioner sidefejl. Der er intet at bekymre sig om!

Andre referencer 2


Sidefejl betyder hukommelsesproblemer


Overvej stigende hukommelse, hvis du har for mange sidefejl.


Har en stor arbejdssæt størrelse.


Arbejdsindstillingen er det sæt hukommelsessider, der aktuelt er indlæst i RAM. Dette måles af Process \ Work Set. En høj værdi kan indikere, at du har indlæst et antal enheder.


Process \ Work Set har ingen specifik tærskelværdi at se, selvom en høj eller varierende værdi kan indikere en hukommelseskort. En høj eller varierende værdi ledsaget af en høj sidefejl tyder tydeligt på, at din server ikke har nok hukommelse.


Yderligere læsning:


Kontroller hukommelsen under Systemressourcer i følgende MSDN-artikel:
http://msdn.microsoft.com/en-us/library/ff647791.aspx#scalenetchapt15\_topic9[2]


Giv venligst nogle kode for at undersøge.

Andre referencer 3


Et muligt svar på dette testes jeg for øjeblikket på min ansøgning. Opbrud dit arbejdssæt i mindre stykker og arbejde med klumperne.


For eksempel har jeg en stor liste over objekter (9000-30000). Hvis jeg opdeler listen i et stykke af 500 eller deromkring ad gangen, skal det opretholde de 500 genstande i hukommelsen, mens jeg arbejder på dem.


Du vil øge eller formindske størrelsen på din chunk, indtil du kan arbejde hurtigt nok med det, at operativsystemet vil opretholde det i hukommelsen. Dette er teori, jeg har ikke testet det endnu. Men det skal fungere.