John Owens
Hope that helps
<John Owens> wrote in message news:4117c467.15...@sybase.com...
datawindow ldw
ldw = CREATE datawindow
then you've got problems. CREATE isn't meant for visual objects, which
a datawindow is. You have to decide if you want a visual object (and
use OpenUserObject()) or a non-visual object (and use a datastore).
As for the memory leak, if the above isn't the issue, I'd start with
CDMatch (http://members.cox.net/bdick/cdmatch.htm) if you've got
Enterprise.
Good luck,
Terry [TeamSybase] and Sequel the techno-kitten
Sequel's Sandbox: http://www.techno-kitten.com
Home of PBL Peeper, a free PowerBuilder Developer's Toolkit.
Version 2.2.06 now available at the Sandbox
See the PB Troubleshooting Guide at the Sandbox
^ ^
o o
=*=
I tried to use the cdmatch program, but it will not open up
our debug file. I dont know if it is too big or what. It
gives the error msg, "Error accessing external object
property : line 147 - wf_reduce_actions of object w_main".
I checked all of my transactions, and we disconnect and
destroy all of them.
The only other things we create besides normal local
variables are dynamic arrays and cursors. However they are
in a window that is opened and closed each cycle that this
program runs, so they should go out of scope after the
window closes shouldn't they? Plus I dont think you need to
destroy either of those objects.
Other than that I don't see anything that would cause a
memory leak. We tried commenting out all of the external
functions we had declared (for zipping and funky32 calls)
and the problem still occurs. Still having problems
pinpointing it since the problem isn't visible until the
entire cycle is over and the memory has almost all been
released (except for the memory leaked of course)
John
Regards,
Dave Fish
Sybase
I have put the garbage collection function in several places
but to no avail. So far everything we have tried besides
commenting out all of the code outright for our export
module doesnt seem to fix the problem.
In short, there is a small interface window that is visible
to the user where he can set the time interval, directories
to export files to, etc. The user presses start. Every
time the time interval hits, this window does a search on a
database table, and for every group of tables entered in the
database (traversed through a cursor) it opens a window
which is basically just a progress bar. This window has
several database transactions where it searches through
tables and exports them and any tables that have foreign key
references to those tabels into flat files. There are
several cursors used, dynamic arrays, and dynamic
datawindows. At the end the collection of flat files is
zipped up, the transactions are disconnected and destroyed,
and the window is closed. Garbage Collection functions are
both inside of this export window and after it is run.
We have tried adding more garbage collection functions, made
sure all of our "CREATE"s have "DESTROY"s, made sure all of
our cursors are closed. The window closes when finished, so
anything else in memory should be out of scope. There are a
few external function calls like feraseall (which is funky i
believe) and a run statement which does a sweep of your
export folder to turn all files to non-read-only before the
feraseall. There is a filehandle check for the finished
attrib window and a Send statement to close that handle.
That's about it. It's a pretty basic program.
We have tried updating powerbuilder to a more recent build
for other issues we thought were powerbuilder related a
couple of weeks ago but that caused other problems in our
system.
John Owens
Just to be sure, to monitor memory consumption, you're using something
task-specific like PerfMon and not something system-generic like Task
Manager, right? Task Manager can indicate an increase in system memory
usage, but given the dozens to hundreds of things that can be going on
in Windows at any given time, it's a notoriously bad tool to identify
a problem with a specific app. Even with a task-specific monitor,
identifying a PB problem as opposed to a problem with a DBMS client
software or an external DLL call is pretty tough.
One place to go through a checklist is the Troubleshooting Guide
mentioned below. It may ring some bells.
Let's back up and go to basics. If you're app is truly consuming more
and more memory, one of two possibilities exist: your program *is*
actually consuming more memory, or it's not.
If you are, then you've got some serious leg work to do. Sometimes
just "matching" CREATEs and DESTROYs isn't sufficient; you have to
consider program flow. I've had to slap people around for putting a
RETURN between a CREATE and DESTROY (and, trust me, you get some
pretty serious looks when you're caught slapping yourself around in
your cubicle <BG>). You should monitor how much data is being
retrieved in any and all datawindows and datastores (a good place to
do this is the ancestor of each of these objects). Also, having some
kind of monitoring code going in your ancestor NVO (another good
reason to follow the PFC model, if you don't have one) might identify
something. I've never used it much, but maybe the Objects in Memory
tab in the debugger might help identify something. Frankly, CDMatch
will give you an incredible short cut on most of these tasks,
identifying which objects are garbage collected, particularly at the
end of the app, when everything not DESTROYed is garbage collected.
Getting this going will help your life immensely.
If you aren't, then it's one of two possibilities: either PB isn't
releasing memory it's using, as designed, or it isn't garbage
collecting.
Since <?>8.0.2</?>, PB has been designed to not release the memory it
consumes. This enhances performance by not having to go beg the OS for
memory allocation every time PB memory usage goes up and down. If you
are retrieving a data set that gets larger by 120K every cycle, then
your observation makes perfect sense, even if the data set is
destroyed. PB is going to keep that memory around for the next time it
needs it.
The other possibility is a lack of garbage collection. While most
people peg this as a time to clean up objects that are created but not
destroyed, a lot of other things get cleaned up that you don't have
control over, like DWOs (a lot are generated when you use dot notation
to access the datawindow contents) and OLEObjects (ironically, again,
the more "dots" you use, the more temporary OLEObjects get generated
for internal purposes). One possibility there is that you are not
letting PB garbage collect when it is designed to collect, when the
app is at "rest", and you are not forcing a garbage collection. The
other possibility is, like Dave says, a bug that PB isn't garbage
collecting something that it should. Until you've covered everything
above, that's going to be a pretty tough call to make. Unfortunately,
the profiling functionality is the only way to identify what has been
garbage collected. Branching off the approach CDMatch uses to identify
what has been garbage collected and where it was created, you could
probably also write something that identified what objects were in
memory at any given point.
This isn't exactly a solution, but maybe it will give you some ideas
to work on.
Good luck,
Terry [TeamSybase] and Sequel the techno-kitten
Sequel's Sandbox: http://www.techno-kitten.com
I have just re-coded the entire thing to be contained in a
user object instead of in a window, and instead of dynamic
datawindows I am using dynamic datastores. I make sure to
create and destroy every datastore, and I create and destroy
the user object every cycle. It seems that the problem
still exists.
I will check for returns between creates and destroys. Also
will check objects in memory in the debugger.
We checked the latest build of powerbuilder and still have
the same problems.
We are running garbage collection often.
To answer your question about datasets, in this test, the
dataset is identical each cycle, so that's not the problem.
John Owens
Mike Kruchten
<John Owens> wrote in message news:4117be1d.7f5...@sybase.com...
As a last resort, you could make the app restart itself once an hour.
Alex
<John Owens> wrote in message news:4119136e.2f1...@sybase.com...
<John Owens> wrote in message news:4117be1d.7f5...@sybase.com...
We are connecting to a Sybase SQL Anywhere 8 database.
What we are trying now is to split the application into 2
smaller apps, one will just open the other every cycle.
This way the 2nd program gets closed after every cycle and
the memory should get cleaned up.