29. august 2003 - 15:36Der er
2 kommentarer og 1 løsning
Metoder/værktøjer til at finde deadlocks
Jeg kæmper i øjeblikket med en eller flere deadlocks på en server. De opstår ca. en gang hvert andet døgn, og da jeg ikke i test kan fremproverkere dem, er de møghamrende svære at finde.
Er der nogen der kender nogle metoder eller værktøjer, som kan hjælpe til med at finde frem til hvor i koden de opstår?
Hvis jeg kunne finde ud af præcis hvor i koden deadlock'en opstår, er det jo til at få den løst...
Man kunne selvfølgelig gå igang med at udarbejde komplette ressourceallokeringsgrafer, men det tager jo pænt lang tid...
Jeg tror optimiseren finder de deadlocks, man er gået ind i (eller mere præcist, hvor i koden man står, når der optræder deadlocks).
Jeg har arbejdet en del med begrebet, og kan da kun give dig nogle retningslinier, som du skal kigge på.
Generelt: En deadlock optræder kun hvis følgende 3 betingelser er opfyldt: a) der er mere end 1 tråd b) der arbejder på fælles data c) og mindst en af dem foretager en skrivning.
Hvis du fjerner bare en af ovenstående ting, kan det ikke optræde deadlocks.
Generelt set, skal du kigge på dine to eller flere tråde. Er deres adfærd klart isoleret i forhold til hinanden (dvs. anvender deres egne instanser af klasser, egne data etc). Sørg for at de gør det. Typisk afleverer man fra den ene tråd til den anden igennem en buffer/kø/stak/whatever. Sørg for at den er trådsikker.
Endelig hvis de fælles objekter du har kræver opdateringer, kan du evt. kigge på immutable pattern. Det har jeg brugt en del til data objekter.
Eks: public class Firkant { private final int x, y; public Firkant(int x, int y) { this.x=x;this.y=y;}
public Firkant move(int xdelta, int ydelta) { return new Firkant(this.x + xdelta, this.y + ydelta); } }
Og endnu en ting.
Sæt alle dine attributter til final. Efterhånden som der optræder compilerfejl, kan du kigge på hver af dem, om du bruger instansen fra mere end en tråd. Hvis du kan gøre mange af attributterne final, er du sikker på, at det ihvertfald ikke er dem, som skaber problemet.
I en klasse som bruger tråde, og dynamiske attributter, skal du ikke gøre dig afhængig af dine instans variable mere end højst nødvendigt. Ret f.eks.: public class X { private Y y; public void setY(Y y) { // y = null is allowed this.y = y; updateGUI(); } public void updateGUI() { textarea.setText(y.getText()); ... // Etc ( } }
til: public class X { private Y y;
public void setY(Y y) { this.y = y; updateGUI(y); }
public updateGUI(Y y2) { textarea.setText(y2.getText()); ... // etc. } }
Endelig er der threadlocals, som er ganske udemærket.
Hints under debug: public void myMethodWhichIMayBeInDoubtWith() { Log.log("myMethod..."+Thread.currentThread().getName()); .. }
Søg derefter loggen for mymethod....med mere end en slags trådnavn.
Ellers kan jeg ikke komme i tanke om mere lige p.t.
Jeg kender godt grundreglerne for undgåelse af deadlocks og har forsøgt at lave nogle ressourceallokeringsgrafer, som intet viste. Nu har jeg lavet mit eget semafor og anvender det så vidt muligt i stedet for synchronized, til angivelse af kritiske regioner. Så har jeg en deamon-tråd, som overvåger alle tråde, og hvis nogen har været mere end 60 sekunder om en aktivitet, interruptes de. Hvis trådene så er blokkeret i mit semafor, vil den smidte InterruptedException resultere i en udskrevet stacktrace, og jeg kan se hvor deadlocken er :)
Det virker.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.