Страница 1 из 1

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

Добавлено: Ср 13 авг 2014 09:06
Kverde
Добрый день, помогите, пожалуйста, разобраться с проблемой.

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

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

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
В приложении исходный код примера.

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

Добавлено: Ср 13 авг 2014 13:49
Alexp
Добрый день,

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

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

Добавлено: Пт 05 сен 2014 11:54
Alexp
Мы исправили это поведение, это исправление войдет в ближайшую версию.

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

Добавлено: Вт 26 июл 2016 12:40
Nikita_V
Ошибка вновь стала повторятся!

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

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

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

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

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

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

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

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

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;