Tell me how to work with the garbage collector? There was never a need to independently control when an object was physically removed, but a problem arose.

The problem emerged from the other: an error (cannot start thread) .

The essence of the problem is that in the cycle connections to the database are opened and closed (to different databases, about several thousand databases are being searched). As it turned out, although the object is created in the using() {} block, even when exiting this block, the connection to the database remains hanging (at the level of the firebird server). All connections will instantly break as soon as the application is closed. I have only one option left: the object, although it closed the connection and the object.Dispose() method was automatically object.Dispose() upon exiting the using block, the object still hangs in memory, and thus object.Dispose() server from breaking the connection to the database. At the support forum .net of the firebird provider, I was told that I had to learn how to physically nail objects, and not rely on garbage collectors. Here I sit now and wonder how to use this hint. The manual did not understand how to use GC.* . More precisely, I tried various options, but the problem did not dare. Maybe I just do not know how to cook? ..

Who faced with the need to physically kill objects, tell me how to get rid of him at the right time, and not when the garbage collector himself considers it necessary.

Thank you in advance.


That's what I see on the server

 Server Version Info --------------------------------------------------------------------------- Server Version: WI-V2.5.1.26351 Firebird 2.5 Server Implementation: Firebird/x86/Windows NT Service Version: 2 Configuration Info --------------------------------------------------------------------------- Base File: D:\Program Files\Firebird_2_5\ Lock File: C:\ProgramData\firebird\ Message File: D:\Program Files\Firebird_2_5\ Security Database: D:\Program Files\Firebird_2_5\security2.fdb Database Info --------------------------------------------------------------------------- Number of connections: 140 Number of databases: 140 

Here is a test program which I checked on your advice:

 FbConnectionStringBuilder builder = new FbConnectionStringBuilder(); builder.Dialect = 3; //builder.DataSource = "localhost"; builder.Password = "masterkey"; builder.UserID = "SYSDBA"; builder.Charset = "WIN1251"; for (int i = 0; i < fileList.Count; i++) { builder.Database = fileList[i]; using (FbConnection connection = new FbConnection(builder.ConnectionString)) { try { Console.WriteLine(string.Format("[{0}] - {1}", i.ToString("0000"), fileList[i])); connection.Open(); Console.WriteLine(string.Format("[{0}] Connected", i.ToString("0000"))); } catch (Exception ex) { Console.WriteLine(string.Format("[{0}] - EXCEPTION {1}" ,i.ToString("0000"), ex.Message)); Console.ReadKey(); } connection.Close(); Console.WriteLine(string.Format("[{0}] Disconnected", i.ToString("0000"))); } GC.Collect(); GC.WaitForPendingFinalizers(); } Console.ReadKey(); 
  • Maybe this is exactly the case, the code need to do unsafe code? - KoVadim
  • Generally speaking, it is strange. For this purpose, the IDisposable interface is intended so that you can destroy an object by command. It is in this method that the connection should break, and if it has not been called explicitly, then in the finalizer. If the provider does not allow creating many objects, even nailing them, it is unlikely that deletion from memory will save. - Modus
  • @Modus, so the trick is that if you close the application, all connections will instantly break ... It seems that the object is not destroyed ... Now there is an idea that opening a request and a separate stream and waiting for its completion can in this case, when nailing the stream, all the connections will be cut off, yet the Windows should correctly clean the memory of the destroyed stream, since I cannot do it in one stream. - pincher1519
  • @KoVadim, tried it. Replaced in the above code of the program using on unsafe, put the creation in the inside of its block, the rest left as well as written in the code. It also did not help. - pincher1519
  • I realized that they would burst. But at the end of the application, a lot of things can happen, except for deleting an object from memory. Roughly speaking, the process is nailed - all the resources used by it are released. Most likely, FbConnection holds not only managed resources, but also unmanaged resources that cannot be accessed through the GC . - Modus

3 answers 3

The problem was not that I did not kill the objects, but that the provider itself keeps a copy of them on them. So when I kill a connection, he still lives inside the provider in the poll.

As it turned out, the solution to the problem lay on the surface. For my needs, I turned off the use of connection pool options using the connection string options and it all worked as it should.

Thank you for concern to my problem.

    You can only recommend inserting two spells after using and zeroing the link:

     GC.Collect(); GC.WaitForPendingFinalizers(); 

    It should help, although it may sift a little performance.

    • @ganouver, I tried it did not help ... = (I cited the program code and the result of its work. Can I find out which objects in the application are created and which will be deleted soon when I call the garbage collector at the desired point of the program code? - pincher1519
    • What's the point? The above code forcibly deletes all old objects. In general, this can be done using the .NET Memory Profiler . Generally, using does not help, dig in the other direction. - Modus
    • somehow it is definitely possible (memory profilers use it), but I didn’t have a deal with it, I don’t know. As a workaround option, select the logic of working with the database into a separate process and launch new processes in a loop. It may also be worth looking closely at the FbConnection methods. Maybe, besides Close, there is also something like a forced release. Still (stupid, but it might work) try not to call Close, but rely on Dispose. Maybe Close frees up not all resources, but puts a label that did everything and Dispose does not work correctly. - ganouver

    Here I have a suspicion that because of this


    you have an object and remain alive ... until the builder nails in the magic and it does not happen ...

    To check, try or kill the builder or initialize it like this:

     using (FbConnection connection = new FbConnection(builder.ConnectionString+"")) 
    • All figured out. I downloaded the source code of the provider and ran through it step by step, watching what he was doing. - pincher1519