Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Memory leaks?
Message
De
31/10/1998 20:05:53
 
 
À
31/10/1998 13:38:51
Information générale
Forum:
Visual FoxPro
Catégorie:
Classes - VCX
Titre:
Divers
Thread ID:
00148261
Message ID:
00153220
Vues:
25
Rick,

David F.'s snippet shows a certain result, but if you run the following hack of David's original code (sorry, but I don't know how to do the formatting stuff) you will see a more ACCURATE picture of the situation.

I offer the following notes on the 'hack':
1) numbers on second FOR... iteration will not be totally accurate, since I added the loop at last minute and did *NOT* make allowances in calculations.

2) There is a SUSPEND *after* the loop, meaning *AFTER* the objects X1 and X2 have been RELEASED. Do a "DISP MEMO" at that point and you will see:
--- at the top of the display, objects X1, X2, Y1 and Y2 are still there;
--- at the bottom of display (after hitting a key until it ends) that "2 windows defined" is printed there.

3) All that the Yx memvar is is a reference to Xx.Tag, but since it is never released it fills the definition of a dangling reference.

4) There can be some doubt about what,exactly, SYS(1016) actually displays as its value. It could be (and probably is, I would *GUESS*, only that memory still accessible through programming. That is, equivalent to what show with a DISP MEMO command. This would be as opposed to displaying all of the actual memory still occupied by the app. regardless of if it is accessible or not.

-------here's the hack ----------
clear
clear all
activate window "debug output"

* debugout "main pre createobject " + sys(1016)
* createobject( "cForm" )
* debugout "main post createobject " + sys(1016)

Base_At_Start_ln= VAL(sys(1016))

? "Starting user-object memory use is ", base_at_start_ln
? " "

debugout "pre create X reference " + sys(1016)

FOR LL = 1 to 2 step 1

LC=str(LL,1,0)

x&LC. = createobject( "cForm" )

Right_After_X&LC._Created_ln= val(sys(1016))

? "Right after form object X&LC. created, user-object mem. at", VAL(sys(1016))
? " "
? "So X&LC. cost in memory is", Right_After_X&LC._Created_ln - Base_at_Start_ln

Cost_of_X&LC._ln= Right_After_X&LC._Created_ln - Base_at_Start_ln && inaccurate on second loop

debugout "main x exists " + sys(1016)
y&LC.= x&LC..tag

After_Y&LC._referencing_X&LC._ln= val(sys(1016))

? " "
? "After making a (later) dangling reference to X&LC.", val(sys(1016))
? " "
? "And the memory cost of Y&LC. is ", After_Y&LC._referencing_X&LC._ln - Right_After_X&LC._Created_ln

debugout "After Y set as reference" + sys(1016)

release x

debugout "after X released, but Y still there" + sys(1016)

After_X&LC._is_Released_ln= val(sys(1016))

? " "
? "Size now occupied by program after X&LC. released", after_X&LC._is_released_ln - base_at_start_ln
? " "

ENDFOR

suspend && On this SUSPEND, do a DISP MEMO in Command Window

define class cForm as Form

procedure Init
this.Tag = replicate( "abcde", 100000 )
this.Visible = .F.
debugout program() + " Init " + sys(1016)
endproc

procedure Destroy
debugout program() + " Destroy " + sys(1016)
endproc

enddefine
----------- end of hack code -----------

I don't know how you read the output (including the DISP MEMO at the end), but it sure tells me that there is an application memory leak going on, which uses up more and more VFP storage (leading to slowdowns), possibly even ending in an OUT OF MEMORY (VFP) condition.

Cheers and Good Luck,

Jim N


>>Rick,
>>
>>In the instance you cite below it may simply be that you are checking too quickly - I wouldn't be surtprised if VFP only does actual cleanup on an intermittent basis.
>>
>I did notice that the memory used did decline a bit after querying it a couple of times with SYS(1016), but it never did recover all the memory used.
>
>>But as for your real problem, are you quite certain that you don't have *any* "dangling references" to the object???
>
>At first I thought I did. But the "experiment" I tried was from the command window. I simply created an object, and then either removed the object, released the object, or set the object reference to null. In each case SYS(1016) reported a significant reduction in available memory.
>
>In the end, I have "solved" the problem by not dynamically creating and releasing objects in my application. Instead, at startup I create all of the object instances I need and simply "recycle" them. I don't think this was the intent of MS, however. BTW you're right about my misuse of the term "memory leak" since the memory is recovered when my VFP app is exited.
>
>Thanks
>
>Rick Grinter
>
>>In case you are unfamiliar with the term, it basically means some memvar containing the object's reference which has *NOT BEEN SET TO NULL* before the RELEASE (or Destroy). That will definitely cause a memory leak in you situation (though some would reject that terminology, reserving it for leaks which generally affect the whole machine).
>>
>>Good Luck,
>>
>>Jim N
>>
>>>>>Has anyone noticed that there is no way of totally freeing up memory after instantiating a class then removing it? I have a system which receives data over a telephone network. In a "good" day I may receive over 10000 events. In the 'old' days (FP2.x) I would use numerous memvars and save events to files. Now I instantiate an object and populate properties of the object before storing interpreted results. Problem is every time I CREATEOBJECT() or AddObject() I loose memory according to SYS(1016). Soon my app slows to a crawl. I am, BTW removing the object RemoveObject() or releasing the reference to it.
>>>>>
>>>>>The only way I have been able to get around this is to create the needed objects at the outset of the app and simply reuse them every time I get a new message.
>>>>>
>>>>>Is this correct? Even from the command window if you CREATEOBJECT() and then release the reference, you can see memory creeping away. The only way to get it back is with a CLEAR ALL.
>>>>>
>>>>>Any thoughts?
>>>>>
>>>>>Rick Grinter
>>>>
>>>>
>>>>Have you tried RELEASE MyClassInstance?
>>>Craig:
>>>
>>>Thanks for the response. I have not only tried RELEASE but when my objects are contained by another I have tried RemoveObject. Try the following from the command window:
>>>
>>>SET CLASSLIB TO MyClassLib
>>>? SYS(1016)
>>>MyClassInstance = CREATEOBJECT('MyClassDef')
>>>? SYS(1016)
>>>RELEASE MyClassInstance
>>>? SYS(1016)
>>>
>>>The results I just now got to the SYS(1016) query were:
>>>
>>>334820
>>>346244
>>>344988
>>>
>>>and this from the command window. When I took my application and commented out all but the creation and release of the objects and printed the SYS(1016) to the screen after each pass, my memory useage continued to creep up in approximately 12000 byte increments.
>>>
>>>Rick Grinter
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform