Board index » delphi » Memory Leak in VCL

Memory Leak in VCL

On and off I have been aware of threads discussing memory leaks in the
Borland Delphi2 C/S VCL's.

Is this true? (I think Yes!)

If there is a patch, whats it called and how can I get it (from Borland
ftp, I known, but what's it called)

Help would really be appreciated

Stephen Novotny

 

Re:Memory Leak in VCL


Quote
Stephen Novotny wrote:

> On and off I have been aware of threads discussing memory leaks in the
> Borland Delphi2 C/S VCL's.

> Is this true? (I think Yes!)

> If there is a patch, whats it called and how can I get it (from Borland
> ftp, I known, but what's it called)

> Help would really be appreciated

> Stephen Novotny

As far as I know the only patches for D2 are the 2.01 patch
and the "system" patch which is on the web site. Apparently
the Delphi R&D team used BoundsChecker (or similar) when
writing D3 and reckon they have caught most of the leaks.

--
Euan Garden                    
BusinessMetrics? Development Team

Email: e...@valstar.co.uk
Web: http://www.valstar.co.uk
---------------------------------------------------
The opinions expressed here are my own
and not those of my employer

Re:Memory Leak in VCL


Hi Stephen!

Quote

> On and off I have been aware of threads discussing memory leaks in the
> Borland Delphi2 C/S VCL's.

> Is this true? (I think Yes!)

And you are right! Bounds Checker (www.numega.com) signals that
memory leaks. Ans...
 Look, some times ago i found this file at the
Borland's ftp site. Now it missing.

***************************************
README FOR UPDATED DELPHI 2 SYSTEM UNIT
***************************************

The updated System.dcu for Delphi 2.01 addresses two problems:
                      ^^^^^^^^^^^^^^^^^!!!

  * The behavior of the FileMode system variable was modified for
    greater backward compatibility.  Non-text files opened
    with Reset() now support all DOS file modes, not only the
    documented 0, 1 and 2. In particular, you can now use shared
    file modes.

  * A bug was fixed in the memory suballocator which caused a
    16-byte memory leak for every freed block.

Install the updated System.dcu by copying it to your Delphi 2.0\Lib
directory.  Then update your component library by selecting
Component|Rebuild Library from the main menu.

*******************
SOURCE CODE CHANGES
*******************

The GetMem.inc and OpenFile.asm modules were modified to accommodate
the above changes to System.dcu.  If you own Delphi Developer or
Delphi Client/Server Suite, then you will find these files in the
...\Delphi 2.0\source\rtl\sys subdirectory.

If you wish to update your installation of the source code to reflect
the changes to System.dcu, then you can follow the directions below
for hand-modification of GetMem.inc and OpenFile.asm.

**********
GETMEM.INC
**********

* Remove FreeBlockDesc() procedure (line 142).

* Replace DeleteBlock() procedure (line 179) with the following code:

  procedure DeleteBlock(bd: PBlockDesc);
  var
    prev, next: PBlockDesc;
  begin
    prev := bd.prev;
    next := bd.next;
    prev.next := next;
    next.prev := prev;
    bd.next := blockDescFreeList;
    blockDescFreeList := bd;
  end;

* Replace MergeBlockAfter() function (line 190) with the following code:

  function MergeBlockAfter(prev: PBlockDesc; const b: TBlock) : TBlock;
  var
    bd, bdNext: PBlockDesc;
  begin
    bd := prev.next;
    result := b;
    repeat
      bdNext := bd.next;
      if bd.addr + bd.size = result.addr then begin
        DeleteBlock(bd);
        result.addr := bd.addr;
        inc(result.size, bd.size);
      end else if result.addr + result.size = bd.addr then begin
        DeleteBlock(bd);
        inc(result.size, bd.size);
      end;
      bd := bdNext;
    until bd = prev;
    if not AddBlockAfter(prev, result) then
      result.addr := nil;
  end;

* Replace FreeSpace() function (line 303) with the following code:

  function FreeSpace(addr: Pointer; maxSize: Integer): TBlock;
  // Free at most maxSize bytes of address space at addr.
  // Returns the block that was actually freed.
  var
    bd, bdNext: PBlockDesc;
    minAddr, maxAddr, startAddr, endAddr: PChar;
  begin
    minAddr := PChar($FFFFFFFF);
    maxAddr := nil;
    startAddr := addr;
    endAddr   := startAddr + maxSize;
    bd := spaceRoot.next;
    while bd <> @spaceRoot do begin
      bdNext := bd.next;
      if (bd.addr >= startAddr) and (bd.addr + bd.size <= endAddr) then
begin
        if minAddr > bd.addr then
          minAddr := bd.addr;
        if maxAddr < bd.addr + bd.size then
          maxAddr := bd.addr + bd.size;
        if not VirtualFree(bd.addr, 0, MEM_RELEASE) then
          heapErrorCode := cReleaseErr;
        DeleteBlock(bd);
      end;
      bd := bdNext;
    end;
    result.addr := nil;
    if maxAddr <> nil then begin
      result.addr := minAddr;
      result.size := maxAddr - minAddr;
    end;
  end;

************
OPENFILE.ASM
************

* Replace line 63:

    MOV    EDX,FILE_SHARE_READ

  with the following four lines:

    MOV    DL,FileMode
    AND    EDX,070H
    SHR    EDX,4-2
    MOV    EDX,dword ptr [@@shareTab+EDX]

* After line 131:

    JMP    @@exit

  and before line 133:

    OpenFile ENDP

  insert the following nine lines:

    @@shareTab:
      DD    FILE_SHARE_READ OR FILE_SHARE_WRITE   ; OF_SHARE_COMPAT    
      DD    0                                     ; OF_SHARE_EXCLUSIVE  
      DD    FILE_SHARE_READ                       ; OF_SHARE_DENY_WRITE
      DD    FILE_SHARE_WRITE                      ; OF_SHARE_DENY_READ  
      DD    FILE_SHARE_READ OR FILE_SHARE_WRITE   ; OF_SHARE_DENY_NONE  
      DD    0
      DD    0
      DD    0

* After line 144:

    MOV    CL,FileMode

  and before line 145:

    CMP    CL,2

  insert the following line:

    AND    CL,3

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

Good luck.
Dmitry.
Moscow.-=RU=-.

Other Threads