Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
A more definitive statement about MEMORY LEAKS within VF
Message
From
01/11/1998 15:10:46
 
General information
Forum:
Visual FoxPro
Category:
Classes - VCX
Miscellaneous
Thread ID:
00153253
Message ID:
00153287
Views:
18
David,

Excuse me for jumping in. I have been following this thread because I tried a test using a loop to see if repeatedly creating and destroying an object would eventually use up all the memory and lock up the machine. It does not, so obviously VFP is recapturing all of the memory used at some point.

But if it does not recapture it all when an object is destroyed, when is it recaptured? VFP does not, like many other languages, have a function which forces a reorganization of memory, which tends to make me nervous as a rule although, admittedly, I have experienced no problems that I am aware of.

regards,

JME

PS: If SYS(1016) is not reliable, what is? How would one go about getting an accurate read on the available memory?

>Jim,
>
>First, As I've already mentioned a couple of places in recent threads SYS(1016) isn't exactly a reliable measurement of memory use. In VFP5a it's better than it was in VFP3 but it's not perfect.
>
>Second, your test code does exactly what you told it to, you've tried to create 99 instances of a 500K form in memory. The external references of the Ynn memvars to the internal textbox object of the form prevent the form from being released. It's no wonder your system ran out of memory at the 87 iteration.
>
>Add this block of code after the loop:
>
>
FOR LL = 1 to 03 step 1
>   LC = ltrim( str( LL, 2, 0 ) )
>   y&LC. = .null.
>   debugout "After nulled Y&LC. " + sys(1016)
>endfor
>
>debugout "at end " + sys(1016)
>
>x = createobject( "cForm" )
>debugout "final x" + sys(1016)
>
>I switched from ? to debugout because it's much more functional.
>
>The sys(1016) memory allocation goes down as each Ynn is nulled out therby allowing the form object to finish it's destruction.
>
>The last creation of another cForm does not take the 500K each of the first 3 did. So that memory pool was reused by VFP, even if sys(1016) didn't go back down to the original base value.
>
>Bottom line is that this is a total non-issue, it's caused entirely by improper coding. Don't expect Microsoft to change VFP so that it corrects a programmer error like this one.
>
>
>>Rick,
>>
>>With a clearer head I have found that the documentation (book - VFP 5 "Developer's Guide" or VFP 6 "Programmer's Guide") is correct with regard to 'dangling references' to an object causing it to remain in memory. Note too that RELEASE gives no indication that this is the case, leaving one to presume that it functioned as expected.
>>
>>The short program below exhibits, on my 64 meg Pentium 233 and with the FOR loop set to do 99 iterations (not 3 as currently coded) fails with a "There is not enough memory..." error on the 88th CreateObject. This is, I would call it, a 'memory leak' within VFP.
>>
>>The run with 99 also runs REAL SLOW after the 8th or 9th CreateObject. Lots of hard-drive activity too, suggesting that SWAP is used from that point on.
>>
>>A second run, typing RESUME to end the first run and changing the FOR loop to execute only 3 times, shows the starting user-object memory usage to be 44,404,408!!! The 'cost of Xx' also shows to be around 9,000 bytes as opposed to just over 500,000 in the first run.
>>
>>I cannot explain this at all.
>>
>>Finally, on ending VFP, the hard drive went crazily for about a minute, presumably clearing the SWAP file.
>>
>>But I do feel that this proves conclusively that a 'dangling reference' *DOES* result in slowness, possibly leading to an out-of-memory condition UNDER THE RIGHT CIRCUMSTANCES.
>>
>>Here's the code, again not nicely formatted for my lack of capability to do so for this medium:
>>
>>clear
>>clear all
>>
>>BaseStartMsg= "Starting user-object memory use is "
>>AfterXCreatedMsg= "user-object mem. right after creating form object "
>>CostOfXMsg= "So cost in memory of "
>>AfterDangleMsg= "After making a (later) dangling reference to "
>>CostOfYCreated= "And the memory cost of "
>>AfterXReleased= "Size now occupied by program after releasing "
>>
>>Base_At_Start_ln= VAL(sys(1016))
>>
>>? BaseStartMsg, base_at_start_ln
>>? " "
>>
>>* Changing the FOR loop to do 99 iterations gave, on my 64meg machine,
>>* a "There is not enough memory to complete this operation", which was
>>* the "this.Tag = replicate. . ." command in cForm.Init, after the 87th Xx object
>>* was created (ie on the 88th object) [ VFP 6.0 in virgin state ]
>>
>>* CURIOSITY: A second run of the program (after changing the loop to run 3 times
>>* and executed right after completion of the first run after resume of
>>* SUSPEND) runs OK but has the following anomolies:
>>* a) Starting user-object memory use is 44,404,408 bytes despite the
>>* program having a CLEAR ALL at the start;
>>* b) Cost of Xx shows to be around 9,000 bytes (in the first run,
>>* done right after starting VFP, it averaged 500,000+ bytes).
>>* TO ME THIS LEADS TO SERIOUS QUESTIONS AS TO JUST WHAT SYS(1016) REPORTS.
>>
>>FOR LL = 1 to 03 step 1
>>
>> LC=ltrim(str(LL,2,0))
>>
>> Size_at_start_of_loop_ln= val(sys(1016))
>>
>> x&LC. = createobject( "cForm" )
>>
>> Right_After_X&LC._Created_ln= val(sys(1016))
>>
>> Cost_of_X&LC._ln= ;
>> Right_After_X&LC._Created_ln - Size_at_start_of_loop_ln
>>
>> ? AfterXCreatedMsg + "X&LC.", VAL(sys(1016))
>> ? CostOfXMsg + "X&LC.", Cost_of_X&LC._ln
>>
>> y&LC.= x&LC..txtBox
>>
>> After_Y&LC._referencing_X&LC._ln= val(sys(1016))
>>
>> Cost_of_Y&LC._ln= ;
>> After_Y&LC._referencing_X&LC._ln - Right_After_X&LC._Created_ln
>>
>> ? AfterDangleMsg + "X&LC.", val(sys(1016))
>> ? CostOfYCreated + "Y&LC.", Cost_of_Y&LC._ln
>>
>> release x&LC.
>>
>> After_X&LC._is_Released_ln= val(sys(1016))
>>
>> ? "Memory cost of Y&LC. after X&LC. released", ;
>> after_X&LC._is_released_ln - After_Y&LC._referencing_X&LC._ln
>> ? " "
>> ? AfterXReleased + "X&LC.", ;
>> after_X&LC._is_released_ln - base_at_start_ln
>> ? " "
>>
>>ENDFOR
>>
>>suspend && On this SUSPEND, do a DISP MEMO in Command Window
>>
>>CLEAR CLASS cForm && attempt to address 2nd run anomolies
>>CLEAR PROGRAM && attempt to address 2nd run anomolies
>>
>>define class cForm as Form
>>
>> ADD OBJECT txtBOX AS TEXTBOX
>>
>> procedure Init
>> this.Tag = replicate( "abcde", 100000 )
>> this.Visible = .F.
>> endproc
>>
>>enddefine
>>
>>Cheers,
>>
>>Jim N
Jim Edgar
Jurix Data Corporation
jmedgar@yahoo.com

No trees were destroyed in sending this message. However, a large number of electrons were diverted from their ordinary activities and terribly inconvenienced.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform