Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeale Ferguson <neale@sinenomine.net>2013-10-10 21:17:17 +0400
committerNeale Ferguson <neale@sinenomine.net>2013-10-10 21:17:17 +0400
commit0b26afc1821c941749ff2d21de86a792b8d889f5 (patch)
tree0182462e7a14b8d9f72f2f2a414cb8048c24e77b /mcs/class/System.Data.OracleClient
parenta55758d13614755cc875446f5039daa9e725d4f3 (diff)
Fix memory leaks in Oracle Client. The largest leaks come from the cursors being created but never freed in OracleParameter.cs. The size of the memory used by these cursors varies from tens to thousands of bytes depending on the statement being executed. Several hours of transactions can lead to OOM errors. The other fixes are relatively minor but they do clean up other unmanaged memory not being returned.
Diffstat (limited to 'mcs/class/System.Data.OracleClient')
-rw-r--r--mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs42
-rw-r--r--mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciStatementHandle.cs9
-rw-r--r--mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs7
-rw-r--r--mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs7
4 files changed, 53 insertions, 12 deletions
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs
index 743a3c72ed8..3e1ce930785 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs
@@ -226,6 +226,11 @@ namespace System.Data.OracleClient.Oci
IntPtr usrmempp);
[DllImport ("oci")]
+ internal static extern int OCICacheFree (IntPtr envhp,
+ IntPtr errhp,
+ IntPtr stmthp);
+
+ [DllImport ("oci")]
internal static extern int OCIAttrGet (IntPtr trgthndlp,
[MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
out IntPtr attributep,
@@ -464,7 +469,7 @@ namespace System.Data.OracleClient.Oci
[MarshalAs (UnmanagedType.SysUInt)] int dstlen,
byte [] src,
[MarshalAs (UnmanagedType.SysUInt)] int srclen,
- [MarshalAs (UnmanagedType.SysUInt)] out int rsize);
+ out long rsize);
[DllImport ("oci")]
internal static extern int OCIUnicodeToCharSet (
@@ -473,7 +478,7 @@ namespace System.Data.OracleClient.Oci
[MarshalAs (UnmanagedType.SysUInt)] int dstlen,
[MarshalAs (UnmanagedType.LPWStr)] string src,
[MarshalAs (UnmanagedType.SysUInt)] int srclen,
- [MarshalAs (UnmanagedType.SysUInt)] out int rsize);
+ out long rsize);
}
#endregion
@@ -774,6 +779,16 @@ namespace System.Data.OracleClient.Oci
xtramem_sz, usrmempp);
}
+ internal static int OCICacheFree (IntPtr envhp,
+ IntPtr svchp,
+ IntPtr stmthp)
+ {
+ #if TRACE
+ Trace.WriteLineIf(traceOci, "OCICacheFree", "OCI");
+ #endif
+ return OciNativeCalls.OCICacheFree (envhp, svchp, stmthp);
+ }
+
internal static int OCIAttrGet (IntPtr trgthndlp,
OciHandleType trghndltyp,
out IntPtr attributep,
@@ -1185,24 +1200,37 @@ namespace System.Data.OracleClient.Oci
byte [] src,
out int rsize)
{
+ int rc;
+ long retSize;
+
#if TRACE
Trace.WriteLineIf(traceOci, "OCICharSetToUnicode", "OCI");
#endif
-
- return OciNativeCalls.OCICharSetToUnicode (svchp, dst, dst!=null ? dst.Capacity : 0, src, src.Length, out rsize);
+ rc = OciNativeCalls.OCICharSetToUnicode (svchp, dst,
+ (dst != null ? dst.Capacity : 0),
+ src, src.Length, out retSize);
+ rsize = (int) retSize;
+ return(rc);
}
internal static int OCIUnicodeToCharSet (
IntPtr svchp,
byte [] dst,
- [MarshalAs (UnmanagedType.LPWStr)] string src,
- [MarshalAs (UnmanagedType.SysUInt)] out int rsize)
+ string src,
+ out int rsize)
{
+ int rc;
+ long retSize;
+
#if TRACE
Trace.WriteLineIf(traceOci, "OCIUnicodeToCharSet", "OCI");
#endif
- return OciNativeCalls.OCIUnicodeToCharSet (svchp, dst, dst!=null ? dst.Length : 0, src, src.Length, out rsize);
+ rc = OciNativeCalls.OCIUnicodeToCharSet (svchp, dst,
+ (dst != null ? dst.Length : 0),
+ src, src.Length, out retSize);
+ rsize = (int) retSize;
+ return(rc);
}
[DllImport ("oci")]
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciStatementHandle.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciStatementHandle.cs
index 31afb5cb324..8bbd545fa4b 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciStatementHandle.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciStatementHandle.cs
@@ -32,6 +32,7 @@ namespace System.Data.OracleClient.Oci {
bool moreResults;
OciServiceHandle serviceHandle;
ArrayList values;
+ ArrayList parm;
OracleCommand command;
#endregion // Fields
@@ -82,12 +83,11 @@ namespace System.Data.OracleClient.Oci {
if (disposing) {
if (values != null) {
- foreach (OciDefineHandle h in values)
+ foreach (OciDefineHandle h in values)
h.Dispose ();
values = null;
}
}
-
base.Dispose (disposing);
}
}
@@ -110,6 +110,9 @@ namespace System.Data.OracleClient.Oci {
OciParameterDescriptor output = new OciParameterDescriptor (this, handle);
output.ErrorHandle = ErrorHandle;
+ if (parm == null)
+ parm = new ArrayList();
+ parm.Add(handle);
return output;
}
@@ -228,6 +231,8 @@ namespace System.Data.OracleClient.Oci {
switch (status) {
case OciGlue.OCI_NO_DATA:
moreResults = false;
+ foreach (IntPtr h in parm)
+ OciCalls.OCIDescriptorFree(h, OciHandleType.Parameter);
break;
case OciGlue.OCI_DEFAULT:
moreResults = true;
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs
index db39d3d551f..8d05612c417 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleCommand.cs
@@ -27,6 +27,7 @@ using System.Data.Common;
using System.Data.OracleClient.Oci;
using System.Drawing.Design;
using System.Text;
+using System.Threading;
namespace System.Data.OracleClient
{
@@ -268,6 +269,7 @@ namespace System.Data.OracleClient
private void BindParameters (OciStatementHandle statement)
{
+Console.Error.WriteLine("{0} - BindParameter",Thread.CurrentThread.ManagedThreadId);
for (int p = 0; p < Parameters.Count; p++)
Parameters[p].Bind (statement, Connection, (uint) p);
}
@@ -705,7 +707,7 @@ namespace System.Data.OracleClient
private void SafeDisposeHandle (OciStatementHandle h)
{
- if (h != null && h != preparedStatement)
+ if (h != null && h != preparedStatement)
h.Dispose();
}
@@ -757,6 +759,9 @@ namespace System.Data.OracleClient
protected override void Dispose (bool disposing)
{
+ if (preparedStatement != null)
+ OciCalls.OCIHandleFree(preparedStatement,
+ OciHandleType.Statement);
if (disposing)
if (Parameters.Count > 0)
foreach (OracleParameter parm in Parameters)
diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
index df17716097d..6f11d970f0d 100644
--- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
+++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs
@@ -821,8 +821,11 @@ namespace System.Data.OracleClient
if (direction == ParameterDirection.Output ||
direction == ParameterDirection.InputOutput ||
direction == ParameterDirection.ReturnValue) {
-
- cursor = IntPtr.Zero;
+ if (cursor != IntPtr.Zero) {
+ OciCalls.OCIHandleFree (cursor,
+ OciHandleType.Statement);
+ cursor = IntPtr.Zero;
+ }
OciCalls.OCIHandleAlloc (connection.Environment,
out cursor,
OciHandleType.Statement,