Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   C# Speicher wird nicht freigegeben (https://www.delphipraxis.net/127983-speicher-wird-nicht-freigegeben.html)

Neutral General 22. Jan 2009 10:21


Speicher wird nicht freigegeben
 
Hi,

Ich bin gerade etwas am verzweifeln. Da lobe ich mir doch die Sprachen, in denen man selbst sichergehen muss/darf dass nicht mehr gebrauchter Speicher brav freigegeben wird.

Der Garbage Collector von C# schafft das scheinbar nicht...

Habe eine Klasse (ServerSocket), die folgende Variable besitzt:

Code:
public List<ClientConnection> Clients = new List<ClientConnection>();
ClientConnection ist dabei eine von mir erstellte Klasse.

Nachdem sich ein Client mit dem Server verbunden hat, wird dieser zu dieser Liste hinzugefügt

Code:
Clients.Add(new ClienConnection(e)); // e = SocketAsyncEventArgs... ist aber nicht so wichtig
Clients[Clients.Count-1].OnDisconnect += ClientDisconnect;
In dieser Klasse findet dann die Kommunikation mit dem Client statt. Wenn der Client die Verbindung beendet wird ClientDisconnect aufgerufen:

Code:
private void ClientDisconnect(object sender, SocketAsyncEventArgs e)
{         
   Clients.Remove(sender as ClientConnection);
   Console.WriteLine("Client Disconnected");   
}
Das Objekt selbst führt keine weiteren Methoden aus. (Ich müsste mich stark irren, falls doch)

Aber der Speicherplatz für das ClientConnection Objekt wird nicht freigegeben. Es gibt meines Wissens keine weiteren Referenzen auf dieses Objekt, bis auf die in der Clients-Liste.

Bin gerade etwas ratlos :gruebel:

Gruß
Neutral General

Khabarakh 22. Jan 2009 11:18

Re: Speicher wird nicht freigegeben
 
Und wie misst du, ob die Instanz freigegeben wurde?
Übrigens, die Klasse enthält doch sicher andere Klassen, die IDisposable implementieren. Dann musst du das Interface ebenfalls implementieren (und beim Disconnet Dispose auch aufrufen), damit unmanaged Ressourcen so schnell wie möglich freigegeben werden.

Neutral General 22. Jan 2009 13:06

Re: Speicher wird nicht freigegeben
 
Hi,

Ich hab es daran gemerkt, dass nachdem 2000 Clients von meinem Server disconnected sind der Speicher nicht geringer wurde.

Richtig sicher war ich mir nachdem ich der ClientConnection Klasse ein 5 MB großes Byte Array verpasst hab.

2 Clients verbinden sich: Arbeitsspeicherverbrauch 12 MB
2 Clients leaven: 12MB

Hab gerade hier den Code nicht zu Verfügung aber wenn ich mich nicht irre enthält meine Klasse eine Socket Variable und eine SocketAsyncEventArgs Variable.

Das mit dem IDisposable Interface funktioniert? Ich glaub da nicht so recht dran... Wie funktioniert das denn in C#?

Khabarakh 22. Jan 2009 14:24

Re: Speicher wird nicht freigegeben
 
Versuch es nochmal mit GC.GetTotalMemory(true), die Angaben dürften verlässlicher sein.
Zitat:

Zitat von Neutral General
Das mit dem IDisposable Interface funktioniert?

Unmanaged Ressourcen wie Handles werden zusammen mit ihrer managed Wrapper-Klasse freigegeben, das muss aber eben nicht sofort nachdem es keine Referenzen mehr auf das Objekt gibt passieren. Wenn du aber genau weißt, dass du das Objekt nicht mehr benötigst, kannst du ihm das über das IDisposable-Pattern mitteilen, dann wirft es seine Handles sofort über Bord.

Neutral General 22. Jan 2009 16:56

Re: Speicher wird nicht freigegeben
 
Hi,

Kannst du mir evtl erklären wie ich das Interface in meine Klasse einbinde und welchen Namespace ich dafür einbinden muss?

Khabarakh 22. Jan 2009 18:31

Re: Speicher wird nicht freigegeben
 
Zitat:

Zitat von Neutral General
Kannst du mir evtl erklären wie ich das Interface in meine Klasse einbinde

In IDisposable.Dispose() rufst du für alle IDisposable-Objekte, die deiner Klasse "gehören", wiederum Dispose() auf.
Zitat:

und welchen Namespace ich dafür einbinden muss?
Ich denke, da wird dir die Hilfe schneller antworten :gruebel: .

Christian S. 22. Jan 2009 19:48

Re: Speicher wird nicht freigegeben
 
Der GC gibt den Speicher doch eh zu einem Zeitpunkt seiner Wahl frei:

Zitat:

Zitat von ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/dv_fxadvance/html/22b6cb97-0c80-4eeb-a2cf-5ed7655e37f9.htm
The .NET Framework's garbage collector manages the allocation and release of memory for your application. Each time you use the newoperator to create an object, the runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it checks for objects in the managed heap that are no longer being used by the application and performs the necessary operations to reclaim their memory.


mr2 22. Jan 2009 20:44

Re: Speicher wird nicht freigegeben
 
Hallo,

probier mal

Clients[Clients.Count-1].OnDisconnect -= ClientDisconnect;

der Delegate hält auch eine Referenz.

mr2

Khabarakh 22. Jan 2009 21:21

Re: Speicher wird nicht freigegeben
 
Zitat:

Zitat von mr2
der Delegate hält auch eine Referenz.

Ja, auf die Form. Aber nicht auf das Objekt, verhindert also keine Collection.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:28 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz