This discussion is archived
0 Replies Latest reply: Dec 21, 2012 2:46 AM by 981210 RSS

Increasing memory when using ODAC 11.2 with Microsoft DTC

981210 Newbie
Currently Being Moderated
Hi, we have a Windows Service application that uses MS DTC with the Oracle.DataAccess code and MSMQ (so we get promoted transactions) with Oracle.DataAccess being used by NHibernate.

We have noticed that over a period of time the memory usage for our process increases indicating a memory leak somewhere... to investigate we obtained a dump file from the process and tried using WinDbg to have a look at what was happening; when we did this we noticed a lot of instances of Oracle.DataAccess.Client.OracleResourceHolder hanging around. Here's the tail of the result of our "!dumphear -stat" command:

000007fee7cbd478 441474 17658960 System.Collections.Stack
000007ff0130f308 441472 24722432 Oracle.DataAccess.Client.OracleResourceHolder
000007fee7ca6ae8 468209 51805352 System.String
000007fee7caaff0 469127 51945440 System.Object[]
000000000011bf10 84691 75661272 Free


From this we can see almost half a million OracleResourceHolder instances, which seems somewhat excessive. Having looked at a few of them with WinDbg we saw they all shared the same output (apologies for the formatting):

MT Field Offset Type VT Attr Value Name
000007fee7ca6ae8 40006b3 8 System.String 0 instance 0000000000000000 m_txnLocalId
000007fee7cbd478 40006b4 10 ...Collections.Stack 0 instance 000000002b846f88 m_stack
000007fee7ca5c40 40006b5 18 System.Object 0 instance 0000000000000000 m_resourceWithLocalTxn
000007ff00bf1278 40006b6 20 ...racleResourcePool 0 instance 0000000000000000 m_oraResPool
000007fee7cad800 40006b7 28 System.Boolean 1 instance 1 m_disposed

They all seem to be disposed but still hanging around in memory, so we then ran the GCRoot command on one of them to see what references were hanging on:

Scan Thread 0 OSTHread 148
Scan Thread 2 OSTHread 1a3c
Scan Thread 5 OSTHread 64c
Scan Thread 6 OSTHread 13ec
Scan Thread 11 OSTHread 1314
Scan Thread 17 OSTHread d5c
Scan Thread 18 OSTHread 17cc
Scan Thread 19 OSTHread 1498
rdx:Root: 000000002b8712a8(Oracle.DataAccess.Client.OracleCommand)->
000000002b86d2f0(Oracle.DataAccess.Client.OracleConnection)->
000000002b86d488(Oracle.DataAccess.Client.OpoConCtx)->
00000000018b2798(Oracle.DataAccess.Client.ConnectionPool)->
00000000018b33b0(Oracle.DataAccess.Client.OracleResourcePool)->
00000000018b3428(System.Collections.Hashtable+SyncHashtable)->
00000000018b33d0(System.Collections.Hashtable)->
0000000012b0dc18(System.Collections.Hashtable+bucket[])->
000000002b872f88(Oracle.DataAccess.Client.OracleResourceHolder)
Scan Thread 20 OSTHread 16bc
Scan Thread 21 OSTHread 1758
Scan Thread 22 OSTHread 1884
Scan Thread 23 OSTHread 1710
Scan Thread 24 OSTHread 1e40
Scan Thread 25 OSTHread 192c
Scan Thread 26 OSTHread 1724
Scan Thread 27 OSTHread 604
Scan Thread 28 OSTHread 1840
DOMAIN(0000000000131220):HANDLE(Pinned):1a17b8:Root: 00000000114db170(System.Object[])->
00000000018b3988(System.Collections.Hashtable+SyncHashtable)->
00000000018b38d0(System.Collections.Hashtable)->
00000000018b3928(System.Collections.Hashtable+bucket[])->
00000000018b2798(Oracle.DataAccess.Client.ConnectionPool)->
00000000018b33b0(Oracle.DataAccess.Client.OracleResourcePool)->
00000000018b3428(System.Collections.Hashtable+SyncHashtable)->
00000000018b33d0(System.Collections.Hashtable)->
0000000012b0dc18(System.Collections.Hashtable+bucket[])->
000000002b872f88(Oracle.DataAccess.Client.OracleResourceHolder)
DOMAIN(0000000000131220):HANDLE(Strong):1a4138:Root: 00000000018b3740(System.Threading._TimerCallback)->
00000000018b36b8(System.Threading.TimerCallback)->
00000000018b2798(Oracle.DataAccess.Client.ConnectionPool)->
00000000018b33b0(Oracle.DataAccess.Client.OracleResourcePool)->
00000000018b3428(System.Collections.Hashtable+SyncHashtable)->
00000000018b33d0(System.Collections.Hashtable)->
0000000012b0dc18(System.Collections.Hashtable+bucket[])->
000000002b872f88(Oracle.DataAccess.Client.OracleResourceHolder)


From what we can tell (we haven't used WinDbg that much so we may be wrong - please feel free to correct if we totally read this the wrong way) it looks like an event handler from the connection pool is keeping a reference to the resource holder.

We know that the distributed transaction is completing as the data is going into the database. Is there anything we could do to mitigate this, have we been doing something wrong in our code, misinterpretted the WinDbg output, or is this a bug?



Thanks, Rich

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points