Unmanaged Memory Leak with CLOB-columns when LegacyEntireLobFetch=0 — oracle-tech

    Forum Stats

  • 3,716,003 Users
  • 2,242,928 Discussions
  • 7,845,734 Comments

Discussions

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Unmanaged Memory Leak with CLOB-columns when LegacyEntireLobFetch=0

Carsten S.
Carsten S. Member Posts: 1
edited March 2019 in ODP.NET

Hi,

I'm new to this group, however I already searched for this topic but did not find any answer. But I wonder if we are the only ones that have this problem?

On customer site (and afterwards reproducable on developer machines) we observed a huge unmanaged memory leak with our application using Oracle 12 via ODP.NET.

We reduced the problem to a small test program - which shows that there might be a problem (bug) with selecting CLOB columns. Early versions of ODP.NET 12 may not have this problem - we observed it with ODP.NET 12.1.2 Release 4 and newer.

The unmanaged memory leak only arises if the parameter LegacyEntireLobFetch is set to 0 in our app.config. ODP.NET 11 does not have this problem, if I am right the default value for LegacyEntireLobFetch was 1 for ODP.NET 11 and changed to 0 for ODP.NET 12.

My question: Do we have a problem in our code? I found no way how to release the unmanaged memory for the CLOB. Or is this a bug in ODP.NET?

Many thanks in advance - i post the small test program below.

Kind regards

Carsten

-----

using System;

using System.Data;

using System.Threading;

using Oracle.DataAccess.Client;

using Oracle.DataAccess.Types;

namespace OracleTest

{

    class Program

    {

        private static volatile bool Finish = false;

        /*
         * Used Table:
            CREATE TABLE CLOBTEST
            (
              GUID RAW(17) NOT NULL,
              TEXT VARCHAR2(20),
              DESCRIPTION CLOB
            );

            INSERT INTO CLOBTEST
            VALUES('ABDE95D8C13A1D419AE17812D6A7C6B2', 'Test', 'Description');
         */

        static void Main()

        {

            Thread selectThread = new Thread(Select);

            selectThread.Start();

            bool c = true;

            Console.WriteLine("g: collect garbage, q: quit");

            while (c)

            {

                string s = Console.ReadLine();

                if (s == "g")

                {

                    GC.Collect();

                    GC.WaitForPendingFinalizers();

                    GC.Collect();

                    Console.WriteLine("Collected garbage");

                }

                else if (s == "q")

                {

                    c = false;

                }

            }

            Finish = true;

            selectThread.Join();

        }

        static void Select()

        {

            const string connectionString =

                "Data Source=ORCL;User Id=DbUser;Password=DbPassword;Validate Connection=true;Max Pool Size=2";

            while (!Finish)

            {

                using (OracleConnection connection = new OracleConnection(connectionString))

                {

                    connection.Open();

                    using (OracleCommand command = connection.CreateCommand())

                    {

                        command.InitialLOBFetchSize = -1;

                        command.CommandText = "SELECT \"GUID\", \"TEXT\", \"DESCRIPTION\" FROM CLOBTEST";

                        // problem does not occur if CLOB column is not selected

                        //command.CommandText = "SELECT \"GUID\", \"TEXT\" FROM CLOBTEST";

                        using (OracleDataReader reader = command.ExecuteReader())

                        {

                            while (reader.Read())

                            {

                                object[] values = new object[reader.FieldCount];

                                reader.GetValues(values);

                                // try to dispose the CLOB explicitly - has no effect

                                //OracleClob clob = reader.GetOracleClob(2);

                                //clob?.Dispose();

                                //clob?.Close();

                            }

                            reader.Close();

                        }

                         command.Transaction?.Dispose();

                    }

                    connection.Close();

                }

            }

            Console.WriteLine("Finished selecting");

        }

    }

}

Tagged:
Sign In or Register to comment.