5 Replies Latest reply: Nov 1, 2013 12:46 AM by Alex.Keh .Product.Manager-Oracle RSS

    Managed odp.net driver 4.121.1.1 memory and handles increase on connection exception bug

    user2160481

      Hello,

      I'm checking the behaivour of the managed odp.net versus no managed odp.net version and I've found a memory and handles increase on the managed version. For checking I've uses two scenarios in a retry connection loop:

       

      1. Error user/password.

      2. Unplup computer from Network / switch off Wifi.

       

      In both scenarios using procexp64.exe on "Performance" tab to check memory and handles.

       

      Results:

      With the no managed driver memory and handles works as spected.

      With the managed driver memory and handles increase in each iteration.

       

       

      The code I use for testing is the following:

       

      class Program
      {
      static void Main(string[] args)
      {

       

      for (int i = 0; i < 10000; i++)
      {
      DatabaseConnection @base = new DatabaseConnection("Oracle.DataAccess.Client", "User Id=mlxnouser; Password=nopassword; Data Source=GIJITSW04/orclmlx");

       

      try
      {
      @base.Open();
      }
      catch (Exception ex)
      {
      Console.WriteLine(ex.Message);
      }
      finally
      {
      @base.Close();
      }

       

      Thread.Sleep(500);

       

      }

       

      Console.WriteLine("Press key to exit.");

       

      Console.ReadKey();

       

      }

       

      private class DatabaseConnection
      {
      protected DbConnection dataBaseConnection;
      protected DbProviderFactory dataBaseProvider;

       

      public DatabaseConnection(string databaseProviderAssembly, string connectionString)
      {
      dataBaseProvider = DbProviderFactories.GetFactory(databaseProviderAssembly);

       

      dataBaseConnection = dataBaseProvider.CreateConnection();

       

      dataBaseConnection.ConnectionString = connectionString;
      }

       

      public void Open()
      {
      dataBaseConnection.Open();
      }

       

      public void Close()
      {
      dataBaseConnection.Close();
      }

       

      }

       

      In my computer is installed the no managed driver. For testing managed driver i downloaded from nuget and i change my App.config with the following code:

       

        <system.data>

          <DbProviderFactories>

            <remove invariant="Oracle.DataAccess.Client" />

            <add name="Oracle.DataAccess.Client" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />

          </DbProviderFactories>

        </system.data>

       

       

      I hope that can be helpfull.

       

      Best Regards

      Jose Luis Vazquez

        • 1. Re: Managed odp.net driver 4.121.1.1 memory and handles increase on connection exception bug
          Alex.Keh .Product.Manager-Oracle

          The Oracle dev team has reproduced your negative test case scenario (i.e. only happens when you encounter errors). We're analyzing it, but were wondering if you have a positive test case scenario. Is that case?

           

          If so, can you either post the positive test case scenario or email it to dotnet_us@oracle.com? If not, we can figure out some way to diagnose, maybe provide some instructions to collect a dump. We'll figure it out by email, if we need to.

          • 2. Re: Managed odp.net driver 4.121.1.1 memory and handles increase on connection exception bug
            user2160481

            I have found one positive scenario when network adapter is disabled or network cable is removed after database connection is stablish.

            • 3. Re: Managed odp.net driver 4.121.1.1 memory and handles increase on connection exception bug
              Alex.Keh .Product.Manager-Oracle

              Can you post the positive test case or send it to dotnet_us@oracle.com? The Oracle dev team will take a look.

              • 4. Re: Managed odp.net driver 4.121.1.1 memory and handles increase on connection exception bug
                user2160481

                The following code is running over a Windows 7 OS.

                 

                After the database connection is stablish all network adapters are disabled. One the connection is close connector adapters are enabled.

                 

                class Program
                {
                    static void Main(string[] args)
                    {
                        List<string> netConnections = LoadConnections();

                 

                        for (int i = 0; i < 10000; i++)
                        {
                            DatabaseConnection @base = new DatabaseConnection("Oracle.DataAccess.Client",
                                "User Id=mlxtrunk; Password=mlx; Data Source=GIJITSW04/orclmlx");

                 

                            try
                            {
                                @base.Open();
                                Console.WriteLine("Connection stablish");
                                Console.ReadKey();
                                DisableConnections(netConnections);

                 

                                DbCommand cmd = @base.dataBaseConnection.CreateCommand();

                 

                                cmd.CommandText = "select 1 from dual";
                                cmd.ExecuteReader();

                 

                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                            finally
                            {
                                @base.Close();
                                EnableConnections(netConnections);
                                GC.Collect();
                                Console.WriteLine("Connection lost");
                                Console.ReadKey();
                            }

                 

                            Thread.Sleep(2000);

                 

                        }

                 

                 

                        Console.WriteLine("Press key to exit.");

                 

                        Console.ReadKey();

                 

                    }

                 

                    private static void EnableConnections(List<string> netConnections)
                    {
                        netConnections.ToList().ForEach(name =>
                        {
                            Console.WriteLine(name);
                            EnableAdapter(name);
                        });
                    }

                 

                    private static void DisableConnections(List<string> netConnections)
                    {
                        netConnections.ToList().ForEach(name =>
                        {
                            Console.WriteLine(name);
                            DisableAdapter(name);
                        });
                    }

                 

                    private static List<string> LoadConnections()
                    {
                        List<string> netConnections = new List<string>();

                 

                        ManagementObjectSearcher adapterSearch = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_NetworkAdapter");

                 

                        foreach (ManagementObject networkAdapter in adapterSearch.Get())
                        {
                            string name = (string)networkAdapter["NetConnectionId"];
                            if (!string.IsNullOrEmpty(name))
                            {
                                netConnections.Add(name);
                                Console.WriteLine(name);
                            }

                 

                        }
                        return netConnections;
                    }

                 

                    private static void EnableAdapter(string adapterName)
                    {
                        ChangeStatusAdapter("ENABLE", adapterName);
                    }

                 

                    private static void DisableAdapter(string adapterName)
                    {
                        ChangeStatusAdapter("DISABLE", adapterName);
                    }

                 

                    private static void ChangeStatusAdapter(string status, string adapterName)
                    {
                        using (Process process = new Process())
                        {

                 

                            ProcessStartInfo cmd = new ProcessStartInfo();
                            cmd.FileName = "Netsh";
                            cmd.Arguments = string.Format("interface set interface \"{0}\" {1}", adapterName, status);

                 

                            process.StartInfo = cmd;

                 

                            process.Start();
                            process.WaitForExit();

                 

                        }
                    }

                 

                    private class DatabaseConnection
                    {
                        public DbConnection dataBaseConnection;
                        protected DbProviderFactory dataBaseProvider;

                 

                        public DatabaseConnection(string databaseProviderAssembly, string connectionString)
                        {
                            dataBaseProvider = DbProviderFactories.GetFactory(databaseProviderAssembly);

                 

                            dataBaseConnection = dataBaseProvider.CreateConnection();

                 

                            dataBaseConnection.ConnectionString = connectionString;
                        }

                 

                        public void Open()
                        {
                            dataBaseConnection.Open();
                        }

                 

                        public void Close()
                        {
                            dataBaseConnection.Close();
                        }

                 

                    }

                 

                }

                 

                In the app.config:

                 

                <?xml version="1.0"?>

                <configuration>

                    <startup>

                        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>

                    </startup>

                 

                  <system.data>

                    <DbProviderFactories>

                      <remove invariant="Oracle.DataAccess.Client" />

                      <add name="Oracle.DataAccess.Client" invariant="Oracle.DataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />

                    </DbProviderFactories>

                  </system.data>

                 

                </configuration>

                 

                • 5. Re: Managed odp.net driver 4.121.1.1 memory and handles increase on connection exception bug
                  Alex.Keh .Product.Manager-Oracle

                  We tried reproducing the bug with the positive test case, but have not been able to. Would you be able to collect dumps on your own machine that reproduces the error, then send the info to dotnet_us@oracle.com?

                   

                  These are the instructions.

                   

                  =========================

                   

                  1) Install "Debugging Tools for Windows" from MSDN that is appropriate for your platform.

                   

                  http://msdn.microsoft.com/library/windows/hardware/ff551063(v=vs.85).aspx

                   

                  2) ADPlus is a tool that can generate .dmp files and it should be part of all flavors of "Debugging Tools for Windows".

                  The following commands will generate the .dmp files:

                   

                  cscript adplus.vbs -hang -pn <process name> -quiet or cscript adplus.vbs -hang -p <process id> -quiet

                   

                   

                  3) Please run the following:

                       i) run the application

                       ii) after 10 minutes of application execution, execute adplus

                       iii) after 20 minutes of application execution, execute adplus

                       iv) after 35 minutes of application execution, execute adplus

                       iv) after 40 minutes of application execution, execute adplus

                   

                       IMPORTANT: Please note that there should be sufficient amount of leakage (i.e. ~1MB leak) seen between each dump files so that we

                       can at least see/determine the reason for the leak.  As such, you may need to consider increasing (or possibly decrease) the intervals

                       so that there's enough (and not too big) of a leakage seen between dumps.

                   

                  4) Please provide us the 4 .dmp file that were generated through adplus and the output from the console application.