Утечка памяти при использовании TOraNestTable

Обсуждение возникших проблем, предложений и ошибок ODAC компонентов

Ответить
Kverde
Сообщения: 9
Зарегистрирован: Ср 13 авг 2014 08:51

Утечка памяти при использовании TOraNestTable

Сообщение Kverde » Ср 13 авг 2014 09:06

Добрый день, помогите, пожалуйста, разобраться с проблемой.

В базе есть пакет с одной процедурой

Код: Выделить всё

create or replace type "INT_ARRAY" is table of integer;

create or replace package test_table is

procedure test(ARM_IDs in int_array);

end test_table;
/

create or replace package body test_table is

procedure test(ARM_IDs in int_array) is
begin
  null;
  null;
end;

end test_table;
/
Создаю модуль с помощью Package Wizard

Код: Выделить всё

unit TestTable;

interface

uses
  {$IFDEF MSWINDOWS} Windows,{$ENDIF} SysUtils, Classes, DB, DBAccess, Ora, OraPackage,
  FMTBcd, OraClasses, OraObjects, OraCall;

type
  TSystem_Test_Table = class(TCustomOraPackage)
  public
    constructor Create(AOwner: TComponent); override;
    procedure Test(const Arm_Ids: TOraNestTable);
  end;

implementation

{ TSystem_Test_Table }

constructor TSystem_Test_Table.Create(AOwner: TComponent);
begin
  inherited;

  PackageName := 'SYSTEM.TEST_TABLE';
end;

procedure TSystem_Test_Table.Test(const Arm_Ids: TOraNestTable);
var
  Arm_Ids_Param: TOraParam;
begin
  BeginExecPLSQL;
  try
    Arm_Ids_Param := AddParam('ARM_IDS', ftDataSet, ptInput);
    Arm_Ids_Param.AsTable := Arm_Ids;
    ExecProc('TEST');
  finally
    EndExecPLSQL;
  end;
end;

end.
В программе включено сообщение об утечках памяти

Код: Выделить всё

program Project2;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  TestTable in 'TestTable.pas';

{$R *.res}

begin
  ReportMemoryLeaksOnShutdown := True; 
Если в следующем коде Table.Free; закоментированно, то при закрытии программы появляется сообщение
An unexpected memory leak has occurred. The unexpected small block leaks are:
1 - 12 bytes: Unknown x 4
53 - 60 bytes: TOraNestTable x 2
Если не закоментированно то появляется ошибка на System_Test_Table.Free;
TOraType.Free RefCount = 0 (D:\Projects\Delphi\Dac\Common\Source\MemData.pas, line 8698)

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var
  Table: TOraNestTable;
  i: Integer;
begin
  Table := TOraNestTable.Create(TOraType.Create(OraSession1.OCISvcCtx, 'INT_ARRAY'));

  i := Table.AppendItem;
  Table.ItemAsInteger[i]:= 2;

  i := Table.AppendItem;
  Table.ItemAsInteger[i]:= 3;

  i := Table.AppendItem;
  Table.ItemAsInteger[i]:= 4;


  System_Test_Table.Test(Table);

  Table.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  OraSession1.Server   := '';
  OraSession1.Password := '';
  OraSession1.Username := '';

  OraSession1.Connect;

  System_Test_Table :=  TSystem_Test_Table.Create(nil);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  OraSession1.Disconnect;

  System_Test_Table.Free;
  //тоже самое с System_Test_Table.Params.Clear;
end;
Delphi 2010, Версия ODAC 9.3.9
В приложении исходный код примера.
Вложения
TestOraBug.7z
(154.83 КБ) 181 скачивание

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

Re: Утечка памяти при использовании TOraNestTable

Сообщение Alexp » Ср 13 авг 2014 13:49

Добрый день,

Спасибо за пример, мы воспроизвели эту ситуацию, и будем исследовать причины такого поведения.

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

Re: Утечка памяти при использовании TOraNestTable

Сообщение Alexp » Пт 05 сен 2014 11:54

Мы исправили это поведение, это исправление войдет в ближайшую версию.

Nikita_V
Сообщения: 1
Зарегистрирован: Вт 26 июл 2016 12:33

Re: Утечка памяти при использовании TOraNestTable

Сообщение Nikita_V » Вт 26 июл 2016 12:40

Ошибка вновь стала повторятся!

Пример:
После нажатия на кнопку:

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var
  Table: TOraNestTable;
  i: Integer;
begin
  Table := TOraNestTable.Create(TOraType.Create(OraSession1.OCISvcCtx, 'INT_ARRAY'));

  i := Table.AppendItem;  //или Table.InsertItem(1); 
  Table.ItemAsInteger[i]:= 1;
 
  i := Table.AppendItem;  //или Table.InsertItem(3); 
  Table.ItemAsInteger[i]:= 3;
  
  i := Table.AppendItem; // или Table.InsertItem(5);
  Table.ItemAsInteger[i]:= 4;

  Table.free;
  //или FreeAndNil(Table);
end;
и выхода из приложения Выходит сообщение об утечки памяти:
An unexpected memory leak has occurred. The unexpected small block leaks are:
13 - 20 bytes: TCRObjectListx2
37 - 44 bytes: UnicodeString x2
53 - 60 bytes: TOraType x 2

RAD Studio 2010
ODAC version 9.7.24 for RAD Studio 2010
ORADeveloper Tools 2.60.178.0
Вложения
TestOraBug.rar
Повтор ошибки
(7.32 КБ) 137 скачиваний

MaximG
Devart Team
Сообщения: 91
Зарегистрирован: Пн 06 июл 2015 12:51

Re: Утечка памяти при использовании TOraNestTable

Сообщение MaximG » Пт 29 июл 2016 12:18

Спасибо за Вашу информацию. Мы воспроизвели ошибку и будем исследовать причины подобного поведения. Мы сообщим Вам о результатах в ближайшее время

MaximG
Devart Team
Сообщения: 91
Зарегистрирован: Пн 06 июл 2015 12:51

Re: Утечка памяти при использовании TOraNestTable

Сообщение MaximG » Пн 01 авг 2016 10:50

Действительно, приведенный Вами пример кода приводит к появлению утечек памяти. Для того, чтобы от них избавиться, необходимо либо явно уничтожать создаваемые Вами объекты :

Код: Выделить всё

procedure TForm1.btSolution1Click(Sender: TObject);
var
  TableType: TOraType;
  Table: TOraNestTable;
  i: Integer;
begin
  TableType := TOraType.Create(OraSession1.OCISvcCtx, 'INT_ARRAY');
  try
    Table := TOraNestTable.Create(TableType);
    try
      i := Table.AppendItem;
      Table.ItemAsInteger[i]:= 1;

      i := Table.AppendItem;
      Table.ItemAsInteger[i]:= 3;

      i := Table.AppendItem;
      Table.ItemAsInteger[i]:= 4;
    finally
      Table.Free;
    end;
  finally
    TableType.Free;
  end;
end;
либо явно не создавать экземпляр TOraType :

Код: Выделить всё

procedure TForm1.btSolution2Click(Sender: TObject);
var
  Table: TOraNestTable;
  i: Integer;
begin
  Table := TOraNestTable.Create;
  Table.AllocObject(OraSession1.OCISvcCtx, 'INT_ARRAY');

  i := Table.AppendItem;
  Table.ItemAsInteger[i]:= 1;

  i := Table.AppendItem;
  Table.ItemAsInteger[i]:= 3;

  i := Table.AppendItem;
  Table.ItemAsInteger[i]:= 4;

  Table.Free;
end;

Ответить