GC-gedrag en CLR-draad kapen

Ik las over de GC in het boek CLR via C# , specifiek over wanneer de CLR een verzameling wil starten. Ik begrijp dat het de threads moet opschorten voordat een verzameling plaatsvindt, maar vermeldt dat dit moet gebeuren wanneer de threadinstructie-aanwijzer een veilig punt bereikt. In de gevallen waarin het niet op een veilig punt staat, probeert het er snel een te krijgen en dit gebeurt door kaping van de thread (een speciale functie-aanwijzer in de threadstack invoegen). Dat is allemaal goed en dandy, maar ik dacht dat managed threads standaard veilig waren?

Ik had aanvankelijk gedacht dat het misschien naar onbeheerde discussies had verwezen, maar de CLR laat onbeheerde discussielijnen verdergaan met het uitvoeren omdat elk gebruikt object hoe dan ook had moeten worden vastgezet.

Dus, wat is een veilig punt in een beheerde thread en hoe kan de GC bepalen wat dat is?

BEWERK:

Ik denk niet dat ik specifiek genoeg was. Volgens dit MSDN-artikel , zelfs als Thread.Suspend wordt aangeroepen, wordt de thread niet opgehangen totdat een veilig punt is bereikt. Vervolgens wordt verder aangegeven dat een veilig punt een punt is in een uitvoering van threads waarop een garbage collection kan worden uitgevoerd.

Ik denk dat ik onduidelijk was in mijn vraag. Ik besef dat een Thread alleen op een veilig moment kan worden opgeschort en ze moeten worden opgeschort voor een GC, maar ik kan geen duidelijk antwoord vinden op wat een veilig punt is. Wat bepaalt een punt in de code als veilig?

12
Veilig door de CLR, niet door de CLR.
toegevoegd de auteur Henk Holterman, de bron

1 antwoord

'Veilige punten' zijn waar we zijn:

  1. Not in a catch block.
  2. Not inside a finally
  3. Not inside a lock
  4. Not inside p/invoke'd call (in managed code). Not running unmanaged code in the CLR.
  5. The memory tree is walkable.

Punt # 5 is een beetje verwarrend, maar er zijn momenten waarop de geheugenboom niet beloopbaar is. Na optimalisatie kan de CLR bijvoorbeeld een object nieuw maken en niet direct aan een variabele toewijzen. Volgens de GC zou dit object een dood voorwerp zijn dat gereed is om te worden verzameld. De compiler geeft de GC opdracht als dit gebeurt om GC nog niet uit te voeren.

Here's a blog post on msdn with a little bit more information: http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx

EDIT: Nou, mijnheer, ik was VERKEERD over # 4. Zie hier in het gedeelte 'Veilige punt'. Als we ons in een p/invoke (unmanaged) codegedeelte bevinden, mag het worden uitgevoerd totdat het weer wordt weergegeven in de beheerde code.

Echter, volgens dit MSDN-artikel , als we ons in een onbeheerde situatie bevinden gedeelte van de CLR-code, dan wordt het niet als veilig beschouwd en zullen ze wachten totdat de code weer wordt beheerd. (Ik was tenminste in de buurt).

13
toegevoegd
Ah, dat is logisch, met name # 5, dat de hele geheugenstructuur in een verifieerbare staat moet zijn voor de GC om een ​​verzameling uit te voeren. Het is een heel eenvoudig concept als je het antwoord hebt, het was alleen maar daar waar ik problemen mee had. Bedankt!
toegevoegd de auteur Christopher Currens, de bron