Properly method to destroy objects

Properly method to destroy objects

Postby pawelu » Wed Oct 11, 2006 3:34 pm

Antonio,

What is properly method to destroy objects in window. I create window with several controls eg. listbox, say, get. When this window is loaded several times memory is not freed after window End() procedure. This generally provide to Internal Error without error description (ca up to 85% load memory use). I try assign object to control and End() or Destroy() method use but no success. Memory usage grow after load window.

Thanks
Pawel
pawelu
 
Posts: 126
Joined: Thu Oct 06, 2005 10:18 pm
Location: Poland

Postby Antonio Linares » Wed Oct 11, 2006 3:46 pm

Pawel,

What FWPPC build (date) are you using ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42098
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby pawelu » Wed Oct 11, 2006 4:26 pm

Antonio,

I use FWPPC 08/September/2006 build.
In EVC Rempte System Information memory usage like this:
program load: 37%
second window with 36 get control load 20 times: 42%
program crash when momory usage is ca 85%

Pawel
Last edited by pawelu on Thu Oct 12, 2006 3:36 pm, edited 1 time in total.
pawelu
 
Posts: 126
Joined: Thu Oct 06, 2005 10:18 pm
Location: Poland

Postby Antonio Linares » Wed Oct 11, 2006 8:54 pm

Pawel,

Please download a more recent FWPPC build, thanks.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42098
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby pawelu » Thu Oct 12, 2006 3:40 pm

Antonio,

This is memory log and test procedure for test with new FWPPC build. It's look like nothing is change.

Regards
Pawel

Memory before: 40,464,384
1 call, before: 40,259,584 after: 39,862,272
2 call, before: 39,862,272 after: 39,727,104
3 call, before: 39,727,104 after: 39,575,552
4 call, before: 39,575,552 after: 39,436,288
5 call, before: 39,436,288 after: 39,284,736
6 call, before: 39,284,736 after: 39,124,992
7 call, before: 39,124,992 after: 38,985,728
8 call, before: 38,985,728 after: 38,825,984
9 call, before: 38,825,984 after: 38,678,528
10 call, before: 38,678,528 after: 38,522,880
11 call, before: 38,522,880 after: 38,375,424
12 call, before: 38,375,424 after: 38,227,968
13 call, before: 38,227,968 after: 38,076,416
14 call, before: 38,076,416 after: 37,916,672
15 call, before: 37,916,672 after: 37,773,312
16 call, before: 37,773,312 after: 37,613,568
17 call, before: 37,613,568 after: 37,474,304
18 call, before: 37,474,304 after: 37,318,656
19 call, before: 37,318,656 after: 37,163,008
20 call, before: 37,163,008 after: 37,027,840
Memory after: 37,027,840
Memory lost: 3,436,544

test procedure:
Code: Select all  Expand view
#Include 'FwCe.Ch'

#Define CRLF Chr (13) + Chr (10)

Function TestMem ()

   Local oWnd := Nil
   Local nHn := 0
   Local i := 0
   Local j := 0
   Local k := 0
   Local aMem := {0, 0}

   nHn := FCreate ('MEM.INFO')
   FWrite (nHn, 'Memory before:' + TransForm (j := MemInfo (), '999,999,999') + CRLF)

   Define Window oWnd Title 'Test Memory'
   @ 226, 176 Button 'Ok' Size 60, 20 Pixel Action (aMem[1] := MemInfo (), NextWnd (++ i), aMem[2] := MemInfo (), MemStatus (nHn, i, aMem))
   Activate Window oWnd

   FWrite (nHn, ' Memory after:' + TransForm (k := MemInfo (), '999,999,999') + CRLF)
   FWrite (nHn, '  Memory lost:' + TransForm (j - k, '999,999,999') + CRLF)
   FClose (nHn)

Return .T.

Function NextWnd (nCnt)

   Local oWnd := Nil
   Local cGet := Space (20)

   Define Window oWnd Title 'Next Window'
   @  24,  5 Get cGet Size 50, 20 Pixel
   @  24, 60 Get cGet Size 50, 20 Pixel
   @  24,120 Get cGet Size 50, 20 Pixel
   @  24,180 Get cGet Size 50, 20 Pixel
   @  46,  5 Get cGet Size 50, 20 Pixel
   @  46, 60 Get cGet Size 50, 20 Pixel
   @  46,120 Get cGet Size 50, 20 Pixel
   @  46,180 Get cGet Size 50, 20 Pixel
   @  68,  5 Get cGet Size 50, 20 Pixel
   @  68, 60 Get cGet Size 50, 20 Pixel
   @  68,120 Get cGet Size 50, 20 Pixel
   @  68,180 Get cGet Size 50, 20 Pixel
   @  90,  5 Get cGet Size 50, 20 Pixel
   @  90, 60 Get cGet Size 50, 20 Pixel
   @  90,120 Get cGet Size 50, 20 Pixel
   @  90,180 Get cGet Size 50, 20 Pixel
   @ 112,  5 Get cGet Size 50, 20 Pixel
   @ 112, 60 Get cGet Size 50, 20 Pixel
   @ 112,120 Get cGet Size 50, 20 Pixel
   @ 112,180 Get cGet Size 50, 20 Pixel
   @ 134,  5 Get cGet Size 50, 20 Pixel
   @ 134, 60 Get cGet Size 50, 20 Pixel
   @ 134,120 Get cGet Size 50, 20 Pixel
   @ 134,180 Get cGet Size 50, 20 Pixel
   @ 156,  5 Get cGet Size 50, 20 Pixel
   @ 156, 60 Get cGet Size 50, 20 Pixel
   @ 156,120 Get cGet Size 50, 20 Pixel
   @ 156,180 Get cGet Size 50, 20 Pixel
   @ 178,  5 Get cGet Size 50, 20 Pixel
   @ 178, 60 Get cGet Size 50, 20 Pixel
   @ 178,120 Get cGet Size 50, 20 Pixel
   @ 178,180 Get cGet Size 50, 20 Pixel
   @ 200,  5 Get cGet Size 50, 20 Pixel
   @ 200, 60 Get cGet Size 50, 20 Pixel
   @ 200,120 Get cGet Size 50, 20 Pixel
   @ 200,180 Get cGet Size 50, 20 Pixel
   @ 222,  0 Say 'Window:' + PadL (nCnt, 3) Size 150, 15 Pixel
   @ 246, 176 Button 'Close' Size 60, 20 Pixel Action oWnd : End ()
   Activate Window oWnd

Return .T.

Function MemStatus (nHn, nCnt, aMem)

   FWrite (nHn, PadL (nCnt, 2) + ' call, before:' + TransForm (aMem[1], '999,999,999') + ' after:' + TransForm (aMem[2], '999,999,999') + CRLF)

Return .T.

#pragma BEGINDUMP

#include <hbapi.h>
#include <windows.h>
#include <aygshell.h>

HB_FUNC (MEMINFO)
{
   MEMORYSTATUS st;
   GlobalMemoryStatus (&st);

   hb_retnl ((ULONG) st.dwAvailPhys);
}

#pragma ENDDUMP
pawelu
 
Posts: 126
Joined: Thu Oct 06, 2005 10:18 pm
Location: Poland

Postby Antonio Linares » Thu Oct 12, 2006 11:25 pm

Pawel,

We are doing some tests with your sample code, thanks.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42098
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Fri Oct 13, 2006 1:00 am

Pawel,

Place a call to hb_gcAll() after closing the second window:
Code: Select all  Expand view
   @ 222,  0 Say 'Window:' + PadL (nCnt, 3) Size 150, 15 Pixel
   @ 246, 176 Button 'Close' Size 60, 20 Pixel Action oWnd : End ()
   Activate Window oWnd
   
   hb_gcAll()

hb_gcAll() invokes the Harbour garbage collector. Anyhow, we keep doing more tests.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42098
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Fri Oct 13, 2006 9:38 am

Pawel,

This sample starts having a memory leak when you click on the button for 20 times or so. We are trying to locate which method is consuming the memory:
Code: Select all  Expand view
#include "FWCE.ch"

static oWnd, oSay, nStart

function Main()

   nStart = MemInfo()

   DEFINE WINDOW oWnd TITLE "MemTest"

   @ 11,  2 SAY oSay PROMPT "Diff: " + Transform( 0, "999,999,999" ) SIZE 150, 20

   @ 13, 13 BUTTON "Go" SIZE 70, 22 ACTION Test()

   ACTIVATE WINDOW oWnd

return nil

function Test()

   local cTest := Space( 10 ), n

   /*
   @ 2,  3 GET cTest SIZE 80, 20
   @ 2, 16 GET cTest SIZE 80, 20
   @ 4,  3 GET cTest SIZE 80, 20
   @ 4, 16 GET cTest SIZE 80, 20
   @ 6,  3 GET cTest SIZE 80, 20
   @ 6, 16 GET cTest SIZE 80, 20
   */

   // @ 2, 2 BUTTON "Test" SIZE 80, 20
   TButtonX():New( 2, 2, "Test",,, 80, 20 )
   TButtonX():New( 4, 2, "Another",,, 80, 20 )

   for n = 3 to Len( oWnd:aControls )
      oWnd:aControls[ n ]:End()
   next   

   hb_gcAll()

   oSay:SetText( "Diff: " + Transform( nStart - MemInfo(), "999,999,999" ) )   
   nStart = MemInfo()
   
return nil   

CLASS TButtonX FROM TButton

   CLASSDATA lRegistered
   
   // METHOD New() INLINE ::Create( "BUTTON" )
   METHOD Initiate() INLINE MsgInfo( "Initiate" )
   METHOD Colors() VIRTUAL
   METHOD GetFont() VIRTUAL
   METHOD HandleEvent() VIRTUAL
   METHOD SetFont() VIRTUAL
   METHOD Register() VIRTUAL
   METHOD Create() VIRTUAL
   METHOD Link() VIRTUAL
   
ENDCLASS   

#pragma BEGINDUMP

#include <hbapi.h>
#include <windows.h>
#include <aygshell.h>

HB_FUNC( MEMINFO )
{
   MEMORYSTATUS st;
   GlobalMemoryStatus( &st );

   hb_retnl( ( ULONG ) st.dwAvailPhys );
}

#pragma ENDDUMP
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42098
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby Antonio Linares » Fri Oct 13, 2006 12:39 pm

Pawel,

Lets check all the static variables of the application with array type, to see if one of them is growing on each call:
Code: Select all  Expand view
static aStatSizes
...
   local n, aSizes

   if aStatSizes == Nil
      aStatSizes = Array( HB_DBG_VMVARSLEN() )
      for n = 1 to HB_DBG_VMVARSLEN()
         if ValType( HB_DBG_VMVARSGET( n ) ) == "A"
            aStatSizes[ n ] = Len( HB_DBG_VMVARSGET( n ) )
         endif
      next       
   else
      for n = 1 to HB_DBG_VMVARSLEN()
         if ValType( HB_DBG_VMVARSGET( n ) ) == "A"
            if aStatSizes[ n ] != Len( HB_DBG_VMVARSGET( n ) )
               MsgInfo( "Static " + Str( n ) + " has grown!" )
            endif   
         endif
      next       
      aSizes = Array( HB_DBG_VMVARSLEN() )
      for n = 1 to HB_DBG_VMVARSLEN()
         if ValType( HB_DBG_VMVARSGET( n ) ) == "A"
            aSizes[ n ] = Len( HB_DBG_VMVARSGET( n ) )
         endif
      next       
      aStatSizes = aSizes
   endif   
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42098
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin for Pocket PC

Who is online

Users browsing this forum: No registered users and 9 guests