|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
How to find a block in Finalize()?I'm using .NET Framework 1.1, C#. A couple of days before I've found out that my application leaks memory not releasing objects with destructors. I'm using some third-party components (Spring.NET and Oracle Data Provider .NET (ODP.NET is actually a leak in my case)). I know that it's a good habit to call Dispose() if the object is IDisposable, but in my case I cannot do this, and need to rely on destructor (performance loss was considered). Then I've tried to reproduce the problem in a small test project (with only ODP.NET objects) and failed :(. The leak was away. Now I suspect that Spring.NET/ODP.NET somehow blocks the finalizer thread, so that it never clears the garbage left. Justification: /// <summary> /// Create a new session /// </summary> /// <returns>The new session that can be used by the client.</returns> public ISession CreateSession() { GC.Collect(); GC.WaitForPendingFinalizers(); //Application hangs here GC.Collect(); GC.WaitForPendingFinalizers(); new Message(Message.MessageType.CalledCreateSessionOn0, this.GetType().FullName).LogDebug(); ISession session = (ISession) Application.CreateSession()[typeof(ISession).FullName+".Remote"]; return session; } This method will be called relatively early after the client starts (server and client interact over normal MarshalByRef objects, there is anyway not much interaction there...). It is practically the first client call on the server side. Before the first client starts there will be some Spring.NET initialization done and an OracleConnection opened and closed (to check that the database is available). The problem is that this code hangs on the first call to GC.WaitForPendingFinalizers(). By "hangs" I mean that nothing else will be done in application - no log messages, in Visual Studio I can pause/stop application (shows me a Console.ReadLine(); line - is not relevant). I've been waiting for 15 minutes - no changes. The memory leak was found out by ANTS Profiler and is definitely there. :( I've also installed WinDBG in order to find out where the finalizing thread is blocked, but had not much advance on that field (starting from that I do not know which of threads is finalizing thread). I have source code for Spring.NET, but it is really huge and not quite understandable. I would be happy if I'll find out that the problem is really in Spring. Can anyone help me, please? Do I actually force the garbage collector in a correct manner (Collect/WaitForFinalizers, Collect/WaitForFinalizers)? How can I find out what the finalizing thread is actually doing? Does the observed behaviour (hang on WaitForPendingFinalizers) actually an evidence that there are problems in finalizer? Thank you in advance. I've found out which of the threads is finally thread, and here is the
output of WinDbg ------------------ ChildEBP RetAddr 0344f6d0 77f4c534 SharedUserData!SystemCallStub+0x4 WARNING: Stack unwind information not available. Following frames may be wrong. 0344f738 77e5ab74 ntdll!NtWaitForSingleObject+0xc 0344f764 4ffcbc90 KERNEL32!WaitForSingleObject+0xf 0344f784 4ffcb252 ole32!StgGetIFillLockBytesOnFile+0xfc77 0344f7f4 4fef252c ole32!StgGetIFillLockBytesOnFile+0xf239 0344f820 77f48a3a ole32!CoRevertToSelf+0x262 0344f824 4ff61d4f ntdll!RtlAllocateHeap+0xe8c 0344f82c 4ffca075 ole32!CoQueryReleaseObject+0x1d7 0344f848 7800c329 ole32!StgGetIFillLockBytesOnFile+0xe05c 00000000 00000000 RPCRT4!NdrComplexStructMarshall+0x201 ------------------ I've also found some interesting material in http://blogs.msdn.com/cbrumme/archive/2004/02/02/66219.aspx and changed (for test purposes) the thread attribute from STAThread to MTAThread. Doesn't help. :( May be any ideas? Show quote "Utwig" wrote: > Hello, > I'm using .NET Framework 1.1, C#. A couple of days before I've found out > that my application leaks memory not releasing objects with destructors. I'm > using some third-party components (Spring.NET and Oracle Data Provider .NET > (ODP.NET is actually a leak in my case)). I know that it's a good habit to > call Dispose() if the object is IDisposable, but in my case I cannot do this, > and need to rely on destructor (performance loss was considered). > Then I've tried to reproduce the problem in a small test project (with only > ODP.NET objects) and failed :(. The leak was away. > Now I suspect that Spring.NET/ODP.NET somehow blocks the finalizer thread, > so that it never clears the garbage left. > > Justification: > > /// <summary> > /// Create a new session > /// </summary> > /// <returns>The new session that can be used by the client.</returns> > public ISession CreateSession() > { > GC.Collect(); > GC.WaitForPendingFinalizers(); //Application hangs here > GC.Collect(); > GC.WaitForPendingFinalizers(); > > new Message(Message.MessageType.CalledCreateSessionOn0, > this.GetType().FullName).LogDebug(); > > ISession session = (ISession) > Application.CreateSession()[typeof(ISession).FullName+".Remote"]; > > return session; > } > > > This method will be called relatively early after the client starts (server > and client interact over normal MarshalByRef objects, there is anyway not > much interaction there...). It is practically the first client call on the > server side. Before the first client starts there will be some Spring.NET > initialization done and an OracleConnection opened and closed (to check that > the database is available). > The problem is that this code hangs on the first call to > GC.WaitForPendingFinalizers(). By "hangs" I mean that nothing else will be > done in application - no log messages, in Visual Studio I can pause/stop > application (shows me a Console.ReadLine(); line - is not relevant). I've > been waiting for 15 minutes - no changes. The memory leak was found out by > ANTS Profiler and is definitely there. :( > I've also installed WinDBG in order to find out where the finalizing thread > is blocked, but had not much advance on that field (starting from that I do > not know which of threads is finalizing thread). > > I have source code for Spring.NET, but it is really huge and not quite > understandable. I would be happy if I'll find out that the problem is really > in Spring. Can anyone help me, please? Do I actually force the garbage > collector in a correct manner (Collect/WaitForFinalizers, > Collect/WaitForFinalizers)? How can I find out what the finalizing thread is > actually doing? Does the observed behaviour (hang on > WaitForPendingFinalizers) actually an evidence that there are problems in > finalizer? > Thank you in advance. |
|||||||||||||||||||||||