PDA

View Full Version : Free Memory problem when using POOM/COM Objects


DirectDance
08-29-2007, 12:45 PM
Hi,

I have a problem re free memory on my PPC, when performing more complex poom commands.

This example is looking for the first contact in the adress book (starting with an a), loading its OID, load the contact itself using the OID and get some properties.

For testing, I have loaded the same contact 10 times (does not make sense in real life, but it is the same if using findnext in a loop).

Here is the piece of code:

#include "swapi.ppl"

//This Sample code will find the first contact, beginning with an A
//and loads the contact and it´s propertys 10 times for testing

func WinMain

struct(lpMem$, MEMORYSTATUS);

GlobalMemoryStatus (&lpMem$);
membefore$ = (lpMem.dwAvailPhys$/1024);
showmessage("Free Memory before executing " % membefore$);

poom$ = CreateCOMObject("PocketOutlook.Application");

result$ = Invoke(poom$, "logon");

folder$ = Invoke(poom$, "GetDefaultFolder", 10);

items$ = GetProperty(folder$, "items");

findcontact$ = invoke(items$, "find", "[LastName] >= \"A\"");

votest$ = getproperty(findcontact$, "oid");


for(u$, 1, 10, 1)

//Einen Datensatz direkt über die OID laden (wenn bekannt)
loadmycontact$ = invoke(poom$, "GetItemFromOid", votest$);

name1$ = getproperty(loadmycontact$, "firstname");
name2$ = getproperty(loadmycontact$, "lastname");
//showmessage(name1$ % ", " % name2$);

end;


Invoke(poom$, "logoff");

invoke(poom$, "Release");
freecomobject(poom$);

GlobalMemoryStatus (&lpMem$);
memafter$ = (lpMem.dwAvailPhys$/1024);

showmessage("Free memory after loop " % int(memafter$));


exit;

end;


What will happen:

Until the for/next command, all is fine, because those commands are only called once.

The loop itself will create 10 com objects to "loadmycontact", I think. The result is, that the memory will go down.

If changing the for/next loop to:

for(u$, 1, 10, 1)

//Einen Datensatz direkt über die OID laden (wenn bekannt)
loadmycontact$ = invoke(poom$, "GetItemFromOid", votest$);

name1$ = getproperty(loadmycontact$, "firstname");
name2$ = getproperty(loadmycontact$, "lastname");
//showmessage(name1$ % ", " % name2$);

invoke(loadmycontact$, "Release"); //INSERTED
freecomobject(loadmycontact$); //INSERTED

end;


than, the created com object should be destroyed in the loop after it was used. Well, in smaller apps like the listed above, it is working very often. But if adding only a few commands to the above listed example, the invoke in the second loop (if u$ >= 2) will crash showing adress misalligned. It seems, that the freecomobject has changed the function "GetItemFromOid", so its parent. Other poom commands down from the poom$ object are still working.

The problem is, if somebody do have 200 contacts on the PPC, by loading them in a loop and displaying them somewhere, the PPC will go out of memory before the result is visible. Adding the freecomobject is resulting in a crash on my PPC.

Anybody with other experiences ??? I have tried a few days to find a solution but have not found one ...

Many thanks,
DirectDance[br]1188391495_11_FT0_memloss.zip

PointOfLight
08-30-2007, 08:37 PM
I've been playing around with your application a little bit, and the last phase of testing was to bump the loop up to 200 and put a log write in each itteration of the loop.* The result as that every time I run the application it crashes on the 16 itteration of the loop.* I also noticed that absolutely no memory is being freed up by the calls to FreeCOMObject.* In fact, in one test I placed the membefore call right before the final block of code where you Invoke release on the poom$ object, and between there and the time you call FreeCOMObject, memory consumption appears to actually increase by 2K.

DirectDance
09-03-2007, 11:43 AM
If I am not wrong, there seems to be a bug in the freecomobject function.

As written in my thread at the top, using freecomobject(loadmycontact$); will crash when the next loadmycontact$ = invoke(poom$, " GetItemFromOid", votest$); is performed.

The poom$ itself is not correct anymore. For testing, I have changed the loop to this:


for(u$, 1, 10, 1)

loadmycontact$ = invoke(poom$, " GetItemFromOid", votest$);

name1$ = getproperty(loadmycontact$, "firstname") ;
name2$ = getproperty(loadmycontact$, "lastname");
//showmessage(name1$ % ", " % name2$);

invoke(loadmycontact$, "Release");
freecomobject(loadmycontact$);

result$ = Invoke(poom$, "logoff");
invoke(poom$, "Release");
freecomobject(poom$);

poom$ = CreateCOMObject("PocketOutlook.Application");
result$ = Invoke(poom$, "logon");

end;


At the end of each loop, poom$ itself is destroeyd and recalled. Then, it works. But this means even more memory will get lost.

PointOfLight
09-04-2007, 04:01 AM
If I am not wrong, there seems to be a bug in the freecomobject function.

I believe this is correct.

As written in my thread at the top, using freecomobject(loadmycontact$); will crash when the next loadmycontact$ = invoke(poom$, " GetItemFromOid", votest$); is performed. The poom$ itself is not correct anymore.

I don't think this is 100% correct. In my testing, it wasn't until the 15th itteration that the loop blew up, and I don't think it's because the poom$ object is "getting lost". I think rather that there is a problem with the way the Invoke and FreeCOMObject calls interoperate. Of course, without knowing the internals I could be speaking completely out of turn.

But this means even more memory will get lost.

This is correct. Hopefully Alain will be able to figure out why the memory isn't being freed up from FreeCOMObject. I truely believe there are two separate problems here, however, since the Invoke problem happens long before available memory runs out.

DirectDance
09-04-2007, 07:36 AM
Thanks Eric for your additional testing and help.

I think you are right, anymore testings by myself doesn´t make sense. I will have to wait for Alain to have a look into this.

Hopefully all is fine with his father, because as we know him, even directly after his marriage he was posting some threads here ... but yesterday nothing.

kornalius
09-04-2007, 01:58 PM
I am still alive and my dad is doing fine. I am still on vacation and will be back to testing next week. I will test your code, chances are that FreeComObject() has a memory leak.

DirectDance
09-04-2007, 03:03 PM
I´m happy to hear ;-)

So, enjoy your vacations.

All the best!
DirectDance

kornalius
09-10-2007, 12:19 PM
Hi,

I have just made a small update (possible leak fixed) to the FreeComObject, please contact me at support@arianesoft.ca and send me that piece of code that doesn't work well. I will try it out and let you know if it fixes the problem.

PointOfLight
09-10-2007, 06:05 PM
Hopefully DirectDance will email you something as well, but I just sent you the sample program I was using to test his problem.

DirectDance
09-12-2007, 08:33 AM
Hi Kornalius,

has the bug you found in the FreeComObject re the memory issue resolved the problem?

The reason why I am asking is, that my (big) first real application is almost finished. But without a fix to the problem, I am not able to finish it at all.

So, It would be very very nice if you can help me ;-)

Regards,
DirectDance

kornalius
09-12-2007, 11:09 AM
DirectDance, I found nothing to work so far. It might not make it for 1.30, sorry. I still have 2 days to work on it though.

kornalius
09-12-2007, 11:28 AM
Actually not true, I have found a few things. There was a memory leak in Invoke and GetProperty when COM objects pointers are returned. I am getting there, slower than I thought but better than nothing.

DirectDance
09-12-2007, 11:38 AM
Kornalius, make me the happiest man if you will see a possibility to include the memory leak (of course, not the memory leak but the resolution) into v1.30.

I will keep my fingers crossed ;-)