I was asked a question about how VFP uses memory:
Recently, on a project to determine and resolve memory leaks in a VFP7 app (which is calling Lotus Notes v4.6), I was using the SYS(1011) function call. One thing I noticed was that the first time I called it, I would get a number (of memory handles). If I then called it again, a slightly different number would appear. If I called it a third time, it would match the second call. Is the second (and third) call the true number of memory handles? Example: At the command window: SET SAFETY OFF CREATE CURSOR w_tmp (fld1 C(50), fld2 B(6)) APPEND BLANK APPEND BLANK APPEND BLANK ? SYS(1011) <-- Returns 1116 ? SYS(1011) <-- Returns 1115 ? SYS(1011) <-- Returns 1115 ZAP ? SYS(1011) <-- Returns 1228 ? SYS(1011) <-- Returns 1224 ? SYS(1011) <-- Returns 1224
Sounds like the Heisenberg Uncertainty Principle at work.
VFP can appear to be idle, perhaps at the command prompt, and yet be doing things in the background. That’s the same with any other application: appearances can be deceiving.
For example, if you move your mouse or type a key when VFP is active, there are many Windows messages that are sent to VFP. You can use SPY to see these messages. VFP also does things in the background that can allocate/free memory.
So what does “true number of memory handles” mean? It’s a number that fluctuates quite a bit, even if it appears that VFP is idle.
Doesn’t that make SYS(1011) useless ? How can you use it to determine if there’s a memory leak?
Put your test in a loop and see if the memory handles grow unexpectedly. (Obviously, if your loop creates objects without releasing them, then at the end of the loop, you’ll have lots of objects and used memory handles.)
What is a memory handle? A memory handle is just a number that represents some allocated memory of a particular size.
Suppose VFP needs to allocate 1000 bytes of memory. It calls a routine that allocates a block of memory and returns a number (called a handle) representing that memory. That memory can be freed by passing that handle to a free routine. Some memory allocations will be needed longer than others, while others might need to be resized as needs change. Memory fragmentation and compaction can occur. The memory could be moved around physically to a different address. .When that memory is used, the handle is passed to a routine that returns the actual physical address of the memory.
The Library Construction Kit memory management functions allow you to allocate/free memory directly in Foxpro. The GlobalAlloc function of the Windows API also returns handles.