Anularea fixării octeților [] care au fost fixați automat într-un server .NET socket

Am un server socket asincron. Am întâlnit o problemă în care clienții problematici și greu de reprodus evenimentele de rețea provoacă un număr nebun de octeți [] pentru a obține fixat. Deoarece toate thread-urile care se ocupă cu clienții sunt implicite (folosesc BeginAcceptClient și folosesc callbacks în loc de fire care sunt explicit instanțiate) Nu controlez procesul de fixare. Prin "filetare implicită" vreau să spun firele generate nu direct de mine, ci de runtime ce găzduiește aplicația mea.

În orice caz, răspunsul din această postare arată modul de blocare a obiectelor. Este posibil să ignorați în spatele scenei fixarea dacă mă duc înainte și îmi pui singur octetul [], fă BeginRead și dezlipi în timpul curățării?

Mulțumiri.

2

2 răspunsuri

Răspunsul din mesajul pe care l-ați conectat este complet greșit (tocmai am lăsat un comentariu acolo). Numai când ultimul mâner de fixare (mai general: fixarea "motivului" deoarece există alte motive decât GCHandles) este eliminat, obiectul este fixat. Nu poți forța să anulezi. Ar fi extrem de nesigur. Ați putea folosi codul gestionat în siguranță pentru a face lucruri nesigure, ceea ce reprezintă chiar o problemă de securitate!

Oricum, nu are sens să încercați să împiedicați fixarea obiectului. Chiar dacă acest lucru a fost posibil, ceea ce nu este, procesul dvs. s-ar prăbuși în momente aleatorii! Priza se bazează pe fixarea pentru corectitudine. Nu face acest lucru fără motiv.

Soluția este în altă parte:

  1. Creați toate tampoanele la pornirea aplicației, astfel încât toate tampoanele să fie contigue în memorie. Utilizați un pool de buffer-e.
  2. Utilizați un număr mic de tampoane mari și alocați secțiuni ale acestora unor clienți individuali.

O notă laterală: Pinning este implementat diferit de ceea ce credeți. Pinning nu este un steag pe care îl puteți activa și dezactiva pe un obiect. Când fixați ceva, la început nu se întâmplă nimic special. Numai atunci când GC rulează, GC observă că există referințe cu proprietatea specială pe care o fixează. Aceasta împiedică apoi mutarea obiectului.

4
adăugat
Minunat multumesc.
adăugat autor kmarks2, sursa

V-aș sugera ca, în loc să vă concentrați pe Pin/Unpin, faceți toate apelurile de la un alt AppDomain. Apoi, atunci când vă aflați într-un punct "inactiv/sigur", descărcați și reîncărcați AppDomain pentru a reseta memoria în stare bună.

1
adăugat
El ar putea să facă doar un GC manual care să elimine toate tampoanele neutilizate, de asemenea. Oprirea unui domeniu de domeniu nu adaugă nicio nouă capacitate în ceea ce privește GC. GC este proces-global.
adăugat autor usr, sursa
Presupun că există scurgeri de mâner. Implementarea BCL Socket nu are niciunul și nu face nici un fel de fixare. Oricum, închiderea domeniului de acces deconectează priza.
adăugat autor usr, sursa
GC este proces-global, dar eliminarea AppDomain va apela toate finalizatorii pe elementele din domeniu; dintre care unul, sperăm, poate fi numit Free pe GCHandle care încă mai deține tampon. Depinde de codul în cauză, dar poate elibera matricea pe care GC o va colecta în următoarea sa mătură.
adăugat autor GWLlosa, sursa
Sunt de acord; închiderea appDomain va deconecta soclul. Dar cineva trebuie să scape ceva; din moment ce unpinning memorie altcineva a fixat este dificil/eroare predispuse, cel mai apropiat cred că puteți obține este de a șterge AppDomain să sperăm că altcineva este într-o poziție mai bună pentru a curăța tampoane. Aceasta presupune că tampoanele nu sunt sub controlul tău.
adăugat autor GWLlosa, sursa