Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

memory leak coz of thread

23 views
Skip to first unread message

Vaishali Kedar

unread,
Dec 12, 2006, 10:46:51 PM12/12/06
to
Hi All,

Checking for low stock status on an independent thread within an
application.

Code -

METHOD cthread() CLASS MainScreen

LOCAL nID AS DWORD
LOCAL phandle AS PTR

phandle := CreateVOThread(NULL_PTR,0,@Checkstocksdis(),NULL_PTR,0,@nID)

RETURN NIL

FUNCTION Checkstocksdis()

LOCAL dbsvrS AS dbserver
LOCAL Firsttime := TRUE AS LOGIC

DO WHILE TRUE
Sleep(10000)
dbsvrS := DBSERVER{Batchingpath+prefix+"StkLvl.dbf",TRUE,FALSE}
IF dbsvrS:status = NULL_OBJECT
dbsvrS:gotop()
IF (dbsvrS:FIELDGET("Stkshow") != dbsvrS:FIELDGET("StkshowP")) .OR.
Firsttime
Firsttime := FALSE
IF dbsvrS:FIELDGET("Stkshow")
IF oBatchingScreen != NULL_OBJECT
oBatchingScreen:oDCFixedText3:show()
ENDIF
ELSE
IF oBatchingScreen != NULL_OBJECT
oBatchingScreen:oDCFixedText3:hide()
ENDIF
ENDIF
ENDIF
dbsvrS:close()
dbsvrS := NULL_OBJECT
ENDIF
Sleep(20000)
ENDDO

RETURN NIL

There is a memory leak there which doesn't happen if I don't run the thread.
What am I doing wrong? The thread gets created once in the application and
then runs during the duration of the application. Will this memory leak
cause the application to shut down spontaneously??

Thanks and regards,
Vaishali


Stephen Quinn

unread,
Dec 12, 2006, 11:49:21 PM12/12/06
to
Vaishali

Probably not the answer your looking for but if you change your code a bit you
need never open the DBServer at all
Eg
// Seeing as your only updating a FT on oBatchScreen there's absolutely no
reason to open the Server if it's NULL

IF oBatchingScreen != NULL_OBJECT

dbsvrS := DBSERVER{Batchingpath+prefix+"StkLvl.dbf",TRUE,FALSE}

IF dbsvrS:Used
// IF dbsvrS:status = NULL_OBJECT
dbsvrS:gotop()

// The field comparison is useless as FirstTime is always TRUE


IF (dbsvrS:FIELDGET("Stkshow") != dbsvrS:FIELDGET("StkshowP"))
.OR.Firsttime

// Useless bit of code as FirstTime isn't used after this
Firsttime := FALSE

IF dbsvrS:FIELDGET("Stkshow")

oBatchingScreen:oDCFixedText3:show()
ELSE
oBatchingScreen:oDCFixedText3:hide()
ENDIF
dbsvrS:close()
ENDIF
dbsvrS := NULL_OBJECT

ENDIF

HTH
Steve


Vaishali Kedar

unread,
Dec 13, 2006, 12:09:47 AM12/13/06
to
Hi Stephen,

Didn't quite understand how the server does not need to be opened at all
........if I don't open it, how do I check the status?

The field comparison is required as it is in a do while true loop - after
the first instance, it will encounter a Firsttime = FALSE. The field
comparison prevents the update if there is no change.

Other than that, do you see an evident error which might cause a leak?

Thanks and regards,
Vaishali

"Stephen Quinn" <stev...@SPbigpondAM.net.au> wrote in message
news:lDLfh.7232$HU....@news-server.bigpond.net.au...

Stephen Quinn

unread,
Dec 13, 2006, 12:56:49 AM12/13/06
to
Vaishali

From your code your only changing the status if
oBatchingScreen != NULL_OBJECT

so if it is (NULL) then there is NO reason to check any status as
oBatchingScreen doesn't exist.

If oBatchingScreen always exists then there is no need to check to see if it's
NULL.

If oBatchingScreen only exists sometimes (ie when the user opens a particular
window) then you should only be executing this thread when it does exist IMO not
for the duration of the apps existence.

> The field comparison is required as it is in a do while true loop - after the
> first instance, it will encounter a Firsttime = FALSE. The field comparison
> prevents the update if there is no change.

OK - missed the While TRUE bit<g>

> Other than that, do you see an evident error which might cause a leak?

Seeing as you've shown no code to close down the thread, how/when do you shut it
down??

If your terminating the thread elsewhere how can you be sure that the Server
isn't open at that point??
Can/does the thread terminate while it sleeps - Are you sure it can/does??

Could that be the reason why your leaking memory??
ie your not giving it time to clean up after itself

HTH
Steve


Vaishali Kedar

unread,
Dec 13, 2006, 1:01:26 AM12/13/06
to
Hi Stephen,

Got that now - the batching screen always exists - that check is probably
redundant - only prevents an error at app startup - and there probably is a
better way of doing it.

The thread exists as long as the application exists - it terminates with the
application.

I don't think the thread terminates while it sleeps. In any case, if I
removethe sleep statements, the leak occurs at approx. the same interval. -
4K at a time.

The memory leak is continuous so unlikely due to a lack of cleanup.

The code within the do while true statement seems (to me) fairly
straightforward and there doesn't seem to be an apparent reason for any
continuous memory allocation.

So am kind of well and truly stuck.

Thanks & regards,
Vaishali

"Stephen Quinn" <stev...@SPbigpondAM.net.au> wrote in message

news:BCMfh.7268$HU....@news-server.bigpond.net.au...

Stephen Quinn

unread,
Dec 13, 2006, 1:39:26 AM12/13/06
to
Vaishali

>>
I don't think the thread terminates while it sleeps. In any case, if I removethe
sleep statements, the leak occurs at approx. the same interval. -4K at a
time.
<<

I think you misunderstood me but if this is happening each time through the loop
then why not open the Server outside your loop and just test the status inside
the loop.
Eg


dbsvrS := DBSERVER{Batchingpath+prefix+"StkLvl.dbf",TRUE,FALSE}
IF dbsvrS:Used

dbsrvS:Gotop()
DO WHILE TRUE
Sleep(10000)


IF (dbsvrS:FIELDGET("Stkshow") != dbsvrS:FIELDGET("StkshowP")) .OR.
Firsttime

Firsttime := FALSE
IF dbsvrS:FIELDGET("Stkshow")

IF oBatchingScreen != NULL_OBJECT
oBatchingScreen:oDCFixedText3:show()
ENDIF
ELSE
IF oBatchingScreen != NULL_OBJECT
oBatchingScreen:oDCFixedText3:hide()
ENDIF
ENDIF
ENDIF

ENDDO
dbsvrS:close()
ENDIF

You still have the problem of closing the Server when you close your app, there
is NO code in here to check for thread termination, so it cannot clean up (ie
close the server) when it terminates (your in a do while true loop without any
exit stategy)

HTH
Steve


G Schaller

unread,
Dec 13, 2006, 2:00:45 AM12/13/06
to
Vaishali.

This is not a good use of threads. In fact, it's a terrible use <g>.

The way you implementing this mechanism gets nothing useful for the use
of the thread and only complicates everything else (and gives you all
this heart burn <g>). You have a very simple timer based checking
mechanism so this is very simply a timer based mechanism!

Use a timer on your oBatchingScreenWindow. Simple! Done...

1. no need for threads or their overhead
2. no GC problems
3. no need for globals
4. no need to test for existence
5. much less code
6. automatic destruction with the window
7. no need for expensive sleeps
8. automatic class references for controls and servers etc

In the window post init, set the timer with this:

DEFINE TIMER_CHECK_STOCK := 567889
SetTimer(SELF:Handle(), TIMER_CHECK_STATUS, 30000, NULL_PTR) // check
every 3 sec

In the Window close or destroy method you have this:

KillTimer(SELF:Handle(), TIMER_CHECK_STATUS)

Now, in your dispatch you have this:

CASE oEvent:wParam = TIMER_EVENT_EXECHECK
IF !oGlobal:UNATTENDED .and. !oGlobal:removealltimers
SELF:CheckStockStatus()
// or do all the processing right here!
ENDIF

So now you just use a method on the window class itself. (The global
stuff is just for demo) Isn't this a little more practical than what you
were trying?

Geoff


G Schaller

unread,
Dec 13, 2006, 2:09:09 AM12/13/06
to
Oops... that was a check for every 30 sec

Dirk (Belgium)

unread,
Dec 13, 2006, 3:36:29 AM12/13/06
to
Hi,

a) I have also found memory leaks with DBServer with memo-fields.
Does your server has a memo-field ???

b) You could change your code, and do not open this dbserver, but
instead read some registry-value. Just for test. Do you have memory
leaks in this way ? Maybe memory leak has nothing to do with the
dbserver, but with the screen.

c) Try the following: Do not use Show() or Hide(), but use direct
api-calls.

Dirk

G Schaller

unread,
Dec 13, 2006, 4:15:55 AM12/13/06
to
Dirk,

> a) I have also found memory leaks with DBServer with memo-fields.
> Does your server has a memo-field ???

How so? We've never had any memory leaks from DBServers. Memo field or
not.

Geoff


Vaishali Kedar

unread,
Dec 13, 2006, 5:42:42 PM12/13/06
to
Sorry Stephen,

I should have mentioned it earlier, but if I comment out the whole code and
just leave the sleep statements in, it has the same effect on memory.

This leads me to think that the problem is not with the server. I know it
sounds wierd but that is what happens. But will try that too again.

Thanks,
Vaishali


"Stephen Quinn" <stev...@SPbigpondAM.net.au> wrote in message

news:yeNfh.7284$HU....@news-server.bigpond.net.au...

Vaishali Kedar

unread,
Dec 13, 2006, 5:48:16 PM12/13/06
to
Geoff,

Understand what you are saying. I have used the timer function in many
places before. Am not sure why I did not do it here.

But will do.....<g>

Thanks
Vaishali

"G Schaller" <geoff@soft_ware.com.au> wrote in message
news:457fa51d$1...@dnews.tpgi.com.au...

Dirk (Belgium)

unread,
Dec 14, 2006, 3:32:19 AM12/14/06
to
Geoff,

Yes, its a leak of about 24 bytes (VO25b3 and CDX-FPT), but before you
see 24 bytes, you have to do a big loop.

It is send to dev, but no reaction at all (like other db-stuff with no
reaction...

If you want, I can search my very old test leak app..

Dirk

G Schaller

unread,
Dec 14, 2006, 3:42:45 PM12/14/06
to
Dirk,

Can you make a small app that proves this?
I'd like to take a look because I still don't believe you <g>.
(...and what's 24 bytes after a big loop???)

Geoff


"Dirk (Belgium)" <dirk.he...@pbprojects.be> wrote in message
news:ts22o2d87hkdb9466...@4ax.com:

Dirk (Belgium)

unread,
Dec 15, 2006, 3:22:51 AM12/15/06
to
Geoff,

It is 24 bytes for each loop !!

But how to see the leak of 24 bytes.
After running it 1000 times...

Dirk

On Thu, 14 Dec 2006 20:42:45 +0000, "G Schaller"

G Schaller

unread,
Dec 15, 2006, 4:18:14 AM12/15/06
to
That's easy:

Collect forced
? dyn mem
For n = 1 upto 1000
Open server
Do stuff
Close server
Next
collectforced
? dyn mem

Maybe its not opening a server but merely accessing the memo field?
Dunno. You write the code and provide the dbf/cdx to go with it and I
will test it for you. BUT if there is a leak, this code will show it.

Geoff


"Dirk (Belgium)" <dirk.he...@pbprojects.be> wrote in message

news:2pm4o21qnudil9prc...@4ax.com:

Robert van der Hulst

unread,
Dec 15, 2006, 4:14:39 AM12/15/06
to
Hi Dirk,
On Thu, 14 Dec 2006, at 08:32:19 [GMT GMT] (which was 9:32 where I live)
you wrote about: 'memory leak coz of thread'

> Yes, its a leak of about 24 bytes (VO25b3 and CDX-FPT), but before you
> see 24 bytes, you have to do a big loop.

> It is send to dev, but no reaction at all (like other db-stuff with no
> reaction...

I am not sure where you have send the memory leak example, but it is not in
our bug database on support.cavo.com., and you also did not send it to me.

I think it is also not fair to state here that you have had no reaction on
questions about db-stuff. I can remember that we had an extensive email
conversation a couple of months ago about the problems you have with
creating your own RDDs.

You even promised to send me the RDD, but I haven't heard from you since
then.

--
Robert van der Hulst
AKA Mr. Data
Vo2Jet & Vo2Ado Support
VO Development Team
www.heliks.nl

Dirk (Belgium)

unread,
Dec 18, 2006, 3:38:41 AM12/18/06
to
Geoff,

Indeed, it has something to do with the memo.
I write it a few messages ago !!!

Friday, I found my example back. I will install it first, and try out
your sample code to look to the leak.

Dirk

On Fri, 15 Dec 2006 09:18:14 +0000, "G Schaller"

Dirk (Belgium)

unread,
Dec 18, 2006, 3:43:07 AM12/18/06
to
Robert,

I write "but I haven't heard from you since then.".

Indeed, it is not completely solved. The problem is the
AppendDB-method in the RDD Classes.

I have send you also this problem, also sven, and even Brian.
Even a guy who has access to VOPS has send this question to you,
but it seems that making a new VO with new editor etc.. is more
important then the resulting program written with VO.

But, OK, This week you will receive the RDD !!

Maybe that make you to decide to change AppendDB.
(And it is not so difficult, because I send already pieces of my code
to Brian for replacement of the AppendDB-method)

Dirk

Dirk (Belgium)

unread,
Dec 21, 2006, 5:06:39 AM12/21/06
to
Geoff,

The example with a DBFLeak is send to your private e-mail.
Please check.

Dirk

Dirk (Belgium)

unread,
Dec 21, 2006, 5:15:11 AM12/21/06
to
Geoff,

What's your email-adress ????
Please send me a simple email, which I can reply...


Dirk

On Fri, 15 Dec 2006 09:18:14 +0000, "G Schaller"

G Schaller

unread,
Dec 21, 2006, 7:30:46 AM12/21/06
to
Dirk,

Got your sample - changed it run on my CDrive - and printed the
debugoutput messages instead of to the status bar and it is clean as a
whistle. No memory leak (Build 2756). Perfect.

Sorry for the bad news <g>.

Geoff

"Dirk (Belgium)" <dirk.he...@pbprojects.be> wrote in message

news:33nko2t57dufbd1cn...@4ax.com:

G Schaller

unread,
Dec 21, 2006, 3:58:30 PM12/21/06
to
..just to explain a little further.

Dirk was using a timer and the statusbar to examine dyn mem usage in a
tight loop. This was always going to show the timer mem increments and
stuff for the status bar. I wrote him a plain loop only using debug
output strings - opening and closing the dbf 1000 times. Takes about 2
seconds. There is no leak.

Now the only difference between Dirk and myself is that I am using Build
2756 and I assume Dirk is on 2740. So unless there is some bug only in
2740, there is no leak.

Geoff

"Dirk (Belgium)" <dirk.he...@pbprojects.be> wrote in message

news:33nko2t57dufbd1cn...@4ax.com:

Dirk (Belgium)

unread,
Dec 22, 2006, 3:36:08 AM12/22/06
to
Geoff,

a) Like I wrote, it is not build 2740, but VO 2.5b-3
b) Like I also wrote, the leak is not inside VO(classes) but, i think,
inside the RDD-Drivers, and because they are written in C, dynamic
memory is not the problem !!! The problem is "Mem Usage" in the
"Windows Task Manager".

Dirk

G Schaller

unread,
Dec 22, 2006, 5:53:08 PM12/22/06
to
Dirk.

VO 2.5! Sheesh! <g>

Get with the program, man! What is goodness name did I waste all that
time for you for? I missed that <g>. Look, my point is simple. There is
no leak I can detect in 2.7 (and I will say I never saw this leak in 2.5
either!) so there is nothing to talk about.

In any event, there is absolutely no use in talking about 2.5 because
there is no possibility that anything could be done about it even if
there was a problem. Nor should there be. 2.5 is old hat and no longer
managed. I don't believe you have a problem and you haven't proved it
yet but of course I cannot compile your test code in 2.5 and nor do I
want to.

I have one piece of simple advice. Upgrade your apps to 2.7

Cheers.

Geoff

"Dirk (Belgium)" <dirk.he...@pbprojects.be> wrote in message

news:736no21219bg5u5lg...@4ax.com:

Dirk (Belgium)

unread,
Dec 27, 2006, 3:34:46 AM12/27/06
to
Tri it today on 2740 !
But I'm sure the bug is still there!

Please, read my comments about dynamic memory, because it is NOT a
leak in dynamic memory, and the only memory you are looking to is this
kind of memory.
You have to use other tools to see this leak in the "windows memory".

Dirk

G Schaller

unread,
Dec 27, 2006, 3:43:28 AM12/27/06
to
There is no leak with 2756 - I can attest to that right now - and I
almost certain there wasn't one with 2740 because we never experienced
one.

"Dirk (Belgium)" <dirk.he...@pbprojects.be> wrote in message

news:7tb4p25vvcs26pp1a...@4ax.com:

Dirk (Belgium)

unread,
Dec 28, 2006, 3:25:41 AM12/28/06
to
Hi Geoff,

Yesterday tested on 2740 ( the latest public update) and also there
the "private bytes" are growing when testing with memo-fields, but
"private bytes" are not growing when testen with a dbf-file without a
memo-field.

Dirk

G Schaller

unread,
Dec 28, 2006, 4:09:46 PM12/28/06
to
Dirk,

As I said to you by email, it is now too difficult to continue working
on this via this forum because you only see an app crash after 14 days
or so of continuous running. None of our apps are run 24/7 so I cannot
compare, except to say that I cannot detect your leak in my current
version.

I also think that as crude as it sounds, if your app only crashes once
in 14 days that you should schedule a restart every 7 days or so. If it
truly only crashes once in 14 days it could be a lot of things.

Cheers.

Geoff

"Dirk (Belgium)" <dirk.he...@pbprojects.be> wrote in message

news:sov6p2h59gb5jtveo...@4ax.com:

0 new messages