T.R | Title | User | Personal Name | Date | Lines |
---|
2508.1 | Is "dislike" too strong a word? | DECWIN::KLEIN | | Fri Mar 23 1990 13:05 | 20 |
| > Does anybody know what the limitations are( if any ) of using this routine.
>Should the customer be reusing the same dialog box by simply doing a
>set values ?
Absolutely. I have heard numerous complaints about XtDestroyWidget, both
in its not really freeing resources and that it has (or at least had) bugs
that were causing applications to ACCVIO.
Even if destroyed widgets free their memory with XtFree, memory quickly becomes
fragmented and the VA space keeps growing.
My advice to anyone who asks is to NEVER use XtDestroyWidget. The
freed resources are often not reusable and its is MUCH MUCH costlier
to destroy a widget and recreate it than to simply do some XtSetValues
to change what it looks like.
Put widgets on a free list rather than destroying them, and look there first
rather than always creating new ones.
-steve-
|
2508.2 | | SCOTMN::WOOD | Richard Wood - UK Workstation Support DTN 833 -3801 | Mon Mar 26 1990 05:02 | 15 |
|
Thanks for the info, Steve, I must say, it does make pretty good sense,
I'll try and persuade the customer to change his approach !!!!
Although I can't see how Virtual Memory can get fragmented with the
little test program in .0 ( creating and freeing the same dialog box ),
I can see how it may do with different widgets; on the whole I can't see
why you should need to destroy a widget if you need to recreate it at a
later time.
Does anybody else have any info on the use of XtDestroyWidget
Thanks
Richard
|
2508.3 | Will this problem be fixed? | ZSAZSA::READINGS | Richard Readings | Mon Mar 26 1990 11:09 | 5 |
| Are there any plans to fix this problem in a future release of DECwindows,
so that memory can be recovered?
Richard
|
2508.4 | Invalid test program... | LEOVAX::TREGGIARI | | Mon Apr 02 1990 17:49 | 33 |
|
> XtRealizeWidget(toplevel);
>
> XtSetArg(arglist[0], DwtNx, 100 );
> XtSetArg(arglist[1], DwtNy, 100 );
> XtSetArg(arglist[2], DwtNheight, 80 );
> XtSetArg(arglist[3], DwtNwidth, 40 );
>
> for (;;)
> {
> bad_destroy = DwtDialogBoxCreate (toplevel,
> "helloworld_main",
> arglist,
> 4);
>
> XtManageChild(bad_destroy);
> XtUnmanageChild(bad_destroy);
> XtDestroyWidget(bad_destroy);
> }
>
> XtMainLoop();
Your test program does not prove that creating and destroying dialog boxes
leaks memory. Widgets attempt to give back all of their instance specific
memory when destroyed. I don't know of any "leaks". What your test program
is doing that will continually eat up memory, is ignoring the X event
queue. Events keep getting queued, but nothing is ever read off...
Steve's suggestion of memory fragmentation is also possible, but I'd rewrite
you test program to keep the queue "clean" before I'd assume that that is
the problem.
Leo
|
2508.5 | Thanks | SCOTMN::WOOD | El Vaquero | Thu Apr 05 1990 13:04 | 4 |
|
Thanks for the response, I'll give it a try.
Richard
|
2508.6 | Try using FAKE_VM | REINIG::REINIG | This too shall change | Fri Apr 06 1990 13:16 | 5 |
| If you are interested in tracking memory leaks and other memory
problems, you may be interested in FAKE_VM. See CLT::FAKE_VM for
details.
August G. Reinig
|
2508.7 | XtDestroyWidget still a problem | SCOTMN::WOOD | El Vaquero | Thu May 17 1990 11:59 | 39 |
|
Hi,
I'm having to resurect this problem; the customer has now come back
with a more complex program to reproduce the problem. It takes into
account clearing out the event queue before destroying the widget. Also
instead of just creating and destroying one widget, it destroys the
whole hierarchy.
Initially, I did suggest that using XtDestroyWidget was probably not
a good idea, but he was insistant that they needed to use it.
I enclose the new program and also a cut down version of my own.
The customers version extends Virtual Address Space comparatively
quickly compared to my own, but seems to ACCVIO after a couple of minutes.
My own version does basically the same as the customers but I've
cut out as much as I could to simplify it and also I wasn't happy with some
of the things he was doing.
Although the build up of Virtual Address Space is slow, it doesn't seem to
stop. Due to the urgency of the problem, I'm having to CLD it. I don't know
whether this problem is directly due to the way XtDestroyWidget works or
whether it is the way it is being used in this case; maybe there is some
method to prevent this build up in VAS.
It also seems that putting a time lag after destroying the widgets
helps reduce the problem.
Does anybody have any ideas about preventing the problem. From reading
an Xtoolkit Programming manual the view was that X applications should not
run for very long anyway, I wonder if this is the only way to approach the
problem, ie. split the application up and fire up bits of it when needed ?
Anyway any help on this problem would be greatly appreciated
Richard
PS. The programs are posted in the next replies
|
2508.8 | detsroy.c - Customers version | SCOTMN::WOOD | El Vaquero | Thu May 17 1990 12:03 | 162 |
| #include <stdio.h>
#include <ssdef.h>
#include <descrip>
#include <decw$include/Dwtwidget.h>
#include <decw$include/DECwDwtApplProg.h>
static XtCallbackProc create_cb();
void monitor_widget();
int libSetTimer();
Widget g_toplevel_widget,g_decw_top, g_widget_arr[100];
long next_widget = 0;
long cnt = 0;
Display *g_display = 0;
DRMHierarchy g_hierarchy;
static DRMType *g_dummy_class;
static char *g_db_filename_vec[] = {"destroy.uid"};
static int g_db_filename_num = (sizeof g_db_filename_vec / sizeof g_db_filename_vec[0]);
static DRMRegisterArg g_reglist[] = {
{"create_cb",(caddr_t)create_cb}
};
static int g_reglist_num = (sizeof g_reglist / sizeof g_reglist [0]);
initialise(argc,argv)
unsigned int argc;
char *argv[];
{
if (DwtFetchWidget (g_hierarchy, "decw_top", g_toplevel_widget,&g_decw_top,
&g_dummy_class) != DRMSuccess)
printf("\nCan't fetch ADIS root window");
XtManageChild(g_decw_top);
g_display = DwtGetDisplay(g_decw_top);
XSynchronize(g_display,1);
}
main(argc,argv)
unsigned int argc;
char *argv[];
{
long status;
DwtInitializeDRM();
g_toplevel_widget = XtInitialize("DECW prob",
"ADIS",
NULL,
0,
&argc,
argv);
status = DwtOpenHierarchy(g_db_filename_num,
g_db_filename_vec,
NULL,
&g_hierarchy );
if (status != DRMSuccess)
printf("\ncan't open hierarchy");
DwtRegisterDRMNames(g_reglist, g_reglist_num);
initialise(argc,argv);
XtRealizeWidget(g_toplevel_widget);
status = libSetTimer("0000 00:00:02.00",monitor_widget,0);
if (status != SS$_NORMAL)
printf("\ncan't set timer");
XtMainLoop();
}
static XtCallbackProc create_cb (widget,tag,reason)
Widget widget;
char *tag;
DwtAnyCallbackStruct *reason;
{
g_widget_arr[next_widget++] = widget;
}
void monitor_widget()
{
long status,
count,
all_dead = 1,
all_alive = 0;
XEvent event;
printf("\nmonitor nextWidget = %d, cnt = %d",next_widget,cnt);
if (next_widget ==10)
{
for (count=0; count<next_widget; count++)
{
all_dead &= g_widget_arr[count]->core.being_destroyed;
all_alive |= g_widget_arr[count]->core.being_destroyed;
}
printf("\ndead = %d, alive = %d",all_alive,all_dead);
cnt++;
if (all_dead)
{
next_widget = 0;
if (DwtFetchWidget(g_hierarchy,
"WIND_1",
g_decw_top,
&g_widget_arr[0],
&g_dummy_class
) != DRMSuccess)
printf("\ncan't fetch ADIS root window");
XtManageChild(g_widget_arr[0]);
}
else if (!all_alive)
{
while (XEventsQueued (g_display, QueuedAfterFlush))
{
XNextEvent(g_display, &event);
}
XtDestroyWidget(g_widget_arr[0]);
}
else
{
printf("\nWaiting");
}
}
status = libSetTimer("0000 00:00:00.01",monitor_widget,0);
if (status != SS$_NORMAL)
printf("\ncan't set monitor timer");
}
int libSetTimer(timstr,proc,flag)
char *timstr;
void *proc;
int flag;
{
long int stat;
long bintim[2];
struct dsc$descriptor_s str_desc = { 16, DSC$K_DTYPE_T, DSC$K_CLASS_S,0};
str_desc.dsc$a_pointer = timstr;
stat = sys$bintim(&str_desc,&bintim);
stat = sys$setimr (flag,&bintim,proc,NULL,0);
return(stat);
}
|
2508.9 | destroy.c - my version | SCOTMN::WOOD | El Vaquero | Thu May 17 1990 12:07 | 116 |
| #include <stdio.h>
#include <ssdef.h>
#include <descrip>
#include <decw$include/Dwtwidget.h>
#include <decw$include/DECwDwtApplProg.h>
static XtCallbackProc create_cb();
void monitor_widget();
Widget toplevel,decwTop, widgetArr[10];
long nextWidget = 0;
long cnt = 0;
Display *dpy = 0;
DRMHierarchy hierarchy;
static DRMType *dummy_class;
static char *filename_vec[] = {"destroy.uid"};
static DRMRegisterArg reglist[] = {
{"create_cb",(caddr_t)create_cb}
};
static int reglist_num = 1;
static int filename_num = (sizeof filename_vec / sizeof filename_vec[0]);
main(argc,argv)
unsigned int argc;
char *argv[];
{
long status;
DwtInitializeDRM();
toplevel = XtInitialize("DECW prob",
"ADIS",
NULL,
0,
&argc,
argv);
status = DwtOpenHierarchy(filename_num,
filename_vec,
NULL,
&hierarchy );
DwtRegisterDRMNames(reglist, reglist_num);
if (status != DRMSuccess)
printf("\ncan't open hierarchy");
if (DwtFetchWidget (hierarchy, "decw_top", toplevel,&decwTop, &dummy_class)
!= DRMSuccess)
printf("\ncan't fetch widget");
XtManageChild(decwTop);
dpy = DwtGetDisplay(decwTop);
XSynchronize(dpy,1);
XtRealizeWidget(toplevel);
for (;;)
{
monitor_widget();
}
}
void monitor_widget()
{
long status;
XEvent event;
/*
printf("\ninside monitor - nextWidget = %d",nextWidget);
*/
if (nextWidget ==0)
{
nextWidget = 1;
if (DwtFetchWidget(hierarchy,
"WIND_1",
decwTop,
&widgetArr[0],
&dummy_class
) != DRMSuccess)
printf("\ncan't fetch ADIS root window");
XtManageChild(widgetArr[0]);
}
else
{
nextWidget = 0;
while (XEventsQueued (dpy, QueuedAfterFlush))
{
XNextEvent(dpy, &event);
}
XtDestroyWidget(widgetArr[0]);
}
}
static XtCallbackProc create_cb (widget,tag,reason)
Widget widget;
char *tag;
DwtAnyCallbackStruct *reason;
{
widgetArr[nextWidget++] = widget;
}
|
2508.10 | destroy.uil | SCOTMN::WOOD | El Vaquero | Thu May 17 1990 12:09 | 186 |
| module decw_prob
version = 'v1.0'
names = case_sensitive
include file 'sys$library:decw$dwtdef.uil';
include file 'decw$include:dwtappl.uil';
procedure
create_cb();
value
toggle_b_label : compound_string('TOGGLE');
object
decw_top : dialog_box {
arguments { width = 500;
height = 200;
units = DwtPixelUnits;
border_width = 0;
};
controls {
dialog_box WIND_1;
};
};
object
WIND_1 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_2;
};
};
object
WIND_2 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_3;
};
};
object
WIND_3 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_4;
};
};
object
WIND_4 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_5;
};
};
object
WIND_5 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_6;
};
};
object
WIND_6 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_7;
};
};
object
WIND_7 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_8;
};
};
object
WIND_8 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_9;
};
};
object
WIND_9 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
controls {
dialog_box WIND_10;
};
};
object
WIND_10 : dialog_box {
arguments { x = 0;
y = 0;
width = 20;
height = 20;
border_width = 4;
};
callbacks {
create = procedure create_cb();
};
};
end module;
|
2508.11 | Almost forgot - versions!! | SCOTMN::WOOD | El Vaquero | Thu May 17 1990 12:35 | 9 |
|
My Workstation - VS3520
Customers - VS3100
VMS version 5.3-2
VAX C version 3.0
Richard
|