Excessive memory use for standard dialog app
Paul -- PHamSmit@sitgtrc1.telecom.com.au
Tuesday, April 16, 1996
Environment: MFC 3.2 ; Symantec C++ 7.21 ; Windows 95
I'm writing a simple application that I want people to leave running in the
background, maybe add to their startup or load as a tray icon, so I decided
to look at the amount of memory that I would be asking them to lock up.
I haven't found anything directly relating to this in all the usual places -
MSDN, MFC FAQ or the MFC list archive.
Here are some rough figures, from looking at free memory use in the Win95
resource meter:
(1) 300K: release version of unmodified MFC dialog box app generated by App
Express (Wizard for you VCers). Contains three command buttons and an About
box.
(2) 500K: release version of unmodified MFC form app generated by App
Express.
(3) 900K: Empty WordPad (Win95 MFC3.2 app)
(4) 25K: Simple C app: a modeless dialog box with several radio and command
buttons. Drives the app with the CreateDialog Win32 API function. Dialog
box resources are managed by a .rc file and can be edited by the Symantec
C++
(similar to VC++) resource editor.
My biggest concern is the size of (1)'s memory requirement. I am conscious
of making even low-end users with 4-6 MB RAM happy.
Why is (1) using MFC so much larger (10x) than a similar thing (4) using
vanilla Win32? Is this just the price we have to pay for the OO approach
(which I would normally happily bear), or is there a significant MFC
resource chunk or two somewhere which I can dispense with in a simple app
like this? I am already compiling using the 'minimise space' release
option.
Any ideas welcome.
regards,
Paul Hampton-Smith
Dean McCrory -- deanm@microsoft.com
Wednesday, April 17, 1996
[Mini-digest: 3 responses]
For memory usage comparisons you might want to create static-link apps
instead of the default (dynamically linked against MFC). Sharing code
via DLLs is usually a 'win' when multiple apps use the DLL, but usually
results in more memory usage for the single app scenario.
Also, you need to realize that in some of your scenarios, the memory
usage actually comes from other components that are part of the system
(print spooler, printer driver, OLE DLLs, etc.) and not directly from
MFC or the MFC app.
You should also watch out for the subtle difference in total memory used
for the "working set" vs. the total memory allocated (the amount of
memory in use while the app is sitting idle is most certainly smaller
than the total allocated by the app).
Finally, I'm assuming that you are testing "Release" build applications,
not "Debug" builds. Debug builds, for obvious reasons, eat up
significantly more memory than their "Release" counterparts.
// Dean
-----From: chucks@skypoint.com (Erik Funkenbusch)
Free memory is not a very accurate way to guage the amount of memory an
application uses. There are many factors that can allocate memory when
execute a program, some of them being disk cache size (which is dynamic
under Win95) System DLL's that are often used by many programs but might
not be loaded when you start you test, and of course, memory management
pools (memory that's allocated by the C runtime library for a "pool" of
memory to decrease allocation time)
> (1) 300K: release version of unmodified MFC dialog box app generated by App
> Express (Wizard for you VCers). Contains three command buttons and an About
> box.
> (2) 500K: release version of unmodified MFC form app generated by App
> Express.
> (3) 900K: Empty WordPad (Win95 MFC3.2 app)
> (4) 25K: Simple C app: a modeless dialog box with several radio and command
> buttons. Drives the app with the CreateDialog Win32 API function. Dialog
> box resources are managed by a .rc file and can be edited by the Symantec
> C++ (similar to VC++) resource editor.
Well, first and foremost is the MFC library overhead. Yes, this is
significant. If this uses the DLL version of MFC then it loads the
MFC40.DLL into memory. This isn't as big of a hit as it might seem,
since many applications use this DLL if they have several apps open
then the memory cost goes way down. If you are statically linking
in the MFC library then this is overhead you will have to bear (but
it's not nearly as large as the full DLL version since it's only
including the classes and code that you are actually using.
Resources are discardable, meaning the system can load them on demand
and throw them away when it needs more memory, so while Resources can
initially take a lot of memory, that memory is only temporary.
> My biggest concern is the size of (1)'s memory requirement. I am conscious
> of making even low-end users with 4-6 MB RAM happy.
You're confusing memory REQUIREMENT with memory USAGE. These really are
2 different things. In Win95, application image memory (code segments, and
resource data, read only data segments) are discardable, they don't get
written to the swap-file, if the system needs more memory, and your app
has pages that it's not using right now it can throw them away and make
the system run much faster. Be aware though, Win95 itself takes up more
than 4 meg of ram, nobody will be happy with *ANY* program even your 25k
one under 4 meg, unless of course they're used to Win 3.1 ;)
> Why is (1) using MFC so much larger (10x) than a similar thing (4) using
> vanilla Win32? Is this just the price we have to pay for the OO approach
> (which I would normally happily bear), or is there a significant MFC
> resource chunk or two somewhere which I can dispense with in a simple app
> like this? I am already compiling using the 'minimise space' release
> option.
MFC is going to be much larger, it's a complex framework that gives you a
*LOT* of functionality, much of which you are probably not using at any
given time. Depending on how you link in MFC you can get better memory
usage, but it's still going to be considerable. This is not the price
of using OO, this is the price of using a complex, full featured class
library. You can write your own OO C++ programs and get similar memory
usage to your C program, but then you don't gain the flexibility of MFC.
The same goes with any full featured library, all those features use
memory.
In short, don't sweat the memory, even if the system has to swap, it's
still going to be *MUCH* faster than Win 3.1.
-----From: Mike.Jones@insoft.com
Paul, (IMHO...)
A couple of things to think about when using AppWizards/Express tools...
Does your sample AppExpress have Print preview, drag drop, toolbars and all
of the 'little' extras that are usually thrown in ?
Your C app probably had 50-100 lines of code, a dialog resource, and
maybe an Icon. Where AppExpress created thousands of lines of code.
If your app needs only to be a tray icon, you (probably) don't need
SDI/MDI, menus, toolbars, print preview, drag/drop, Frames & Views,
and maybe full Context Help.
Try the same model using MFC directly/manually: create a single CWinApp
derived object, override InitInstance() and Run(), and try displaying
a simple CDialog (via DoModal). Now you can get a better idea of how
large your app would be, using only the parts of MFC that you need.
(my Release sample was ~100k with Static MFC, 8k with DLL MFC, using all
default project options, I used VC 4.1, Win 95)
Also, what part of your app will actually be in memory at any given time ?
Remember the 80/20 rule. Unused code pages sit on disk in the EXE and
are loaded when needed (of course, large app + low memory ~= thrashing).
Have fun,
-Mike
--------------------------------------------------------------------
Mike Jones | InSoft, Inc.
email: Mike.Jones@InSoft.com | Executive Park West One.
phone: 1 717 730 9501 x182 | 4718 Old Gettysburg Rd. Suite 307
fax: 1 717 730 9504 | Mechanicsburg, PA 17055
http://www.insoft.com | USA
--------------------------------------------------------------------
/* small stupid sample program, don't grade on style please */
/* displays a dialog with Ok/Cancel, does nothing else */
#include "stdafx.h"
#include "resource.h"
#include "mydialog.h" << dumby CDialog/ClassWizard created dialog with Ok/Cancel only
class MyApp : public CWinApp
{
public:
MyApp() {};
BOOL InitInstance(void) { return CWinApp::InitInstance(); }
BOOL Run(void);
};
MyApp theApp;
BOOL MyApp::Run(void)
{
CMyDialog dlg;
dlg.DoModal();
return ExitInstance();
}
| Вернуться в корень Архива
|