How to find a block in Finalize()?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

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.
 
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?

Utwig said:
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.
 
The problem is found. It was really STAThread attribute. I've definitely
missed something in the first try. Recommend everybody (who are not acquinted
with the topic) to read the link provided in the second post
 
Back
Top