[Mono-dev] OracleClient.Oci and GC

Rodrigo Kumpera kumpera at gmail.com
Mon Aug 25 16:54:16 UTC 2014


Finalization is not deterministic, it depends on the GC been able to
collect all related objects.

Maybe you have things keeping some of those 700 objects around?

The way I test those things in a way that is reasonably reliable is:

var t = new Thread (myTest);

t.Start ();
t.Join ();

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

//now verify the result.




On Mon, Aug 25, 2014 at 11:08 AM, Neale Ferguson <NealeFerguson at verizon.net>
wrote:

> I implemented a Dispose method for OracleParameter:
>
>                 ~OracleParameter ()
>                 {
>                         Dispose(false);
>                 }
>
>                 public void Dispose ()
>                 {
>                         Dispose (true);
>                 }
>
>                 void Dispose (bool disposing)
>                 {
>                         if (disposing) {
>                                 GC.SuppressFinalize(this);
>                         }
>                         if (indicator != IntPtr.Zero) {
>                                 Marshal.FreeHGlobal (indicator);
>                                 indicator = IntPtr.Zero;
>                         }
>                 }
>
> However, when I run the test program I see 1251 constructors being run but
> only 572 destructors/disposals. How do I reconcile this disparity?
>
> Neale
>
> On Aug 22, 2014, at 11:40 AM, Neale Ferguson <NealeFerguson at verizon.net>
> wrote:
>
> > Thanks. I've made changes to OciDefineHandle and have cured nearly all
> the failures I had been experiencing. I have started on OracleParameter as
> it has an object called indicator that is used by the OCIBindxxx calls and
> appears to suffer from the same problem. I was allocating the object in
> native memory in the constructors and was going to free them in a
> destructor. However, in my test runs I see I'm allocating 1200+ objects but
> only freeing ~900. Would you elaborate on your final comment "failing to
> dispose..." as I'm reading this as I don't need to Marshal.FreeHGlobal()
> the object I allocated in the constructors.
> >
> > Neale
> >
> > On Aug 22, 2014, at 11:31 AM, Rodrigo Kumpera <kumpera at gmail.com> wrote:
> >
> >> Hey Neale,
> >>
> >> You can safely pass interior pointers to pinvoke without fearing the
> object been collected for the duration of the call.
> >> Mind that you have to correctly use specify in/out/ref depending on the
> copy semantics you need.
> >>
> >> Problems only arise when native keeps that pointer after the call
> finishes, this can result in the object been moved
> >> as the GC has no visibility into the native heap.
> >>
> >> For those cases you can either create a pinning GC handle to the victim
> object or you can allocate a chunk of native
> >> memory that will be shared between managed and native to store the
> desired value. Both options suck, TBH.
> >>
> >> I'd say go with the native chunk of code if you can't lexically scope
> the pinning regions, it will be more reliable as
> >> failing to dispose the object won't lead to permanent leaks.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/mono-devel-list/attachments/20140825/bd57370f/attachment.html>


More information about the Mono-devel-list mailing list