Improve company productivity with a Business Account.Sign Up


Out of memory - too many symbols

Posted on 1998-09-23
Medium Priority
Last Modified: 2008-02-01
I have a visual basic 3 application, with contains
only one form (with many controls and functions)
and a number of .bas files.
when I tried to add a new function or to declare a variable
inside a function on the form I receive the following message:
"Out of Memory - Too many symbols in form or module".
I transferred many function and global variables to a .bas
file but still i get the same error message.

Any suggestions?
Question by:amnav
LVL 14

Accepted Solution

waty earned 800 total points
ID: 1436174
Here is part of a document I wrote some years ago for VB3 about limits, ... : Windows Limits
Windows version 3.1 imposes a limit of 600 windows in existence at one time. All windows in all applications running in Windows count toward this limit. In Visual Basic, each form and non-graphical control (all controls except shape, line, image, and label) counts as one window. Application Limits
 There can be a maximum of 256 distinct objects in a project.
 There can be a maximum of approximately 230 forms in a project, with up to 80 loaded at one time.
 The total count of all procedures, form and code modules, and DLL declarations must be less than 5,200, not counting event procedures that are empty of code. Forms Limits
 There can be a maximum of 470 controls on a single form, depending on control type.
 There can be a maximum of 254 different control names per form. A control array counts as one name.
 The data in all form properties and all control properties on a given form is stored in a single data segment limited to 64K, except for the List property of combo and list-box controls and the Text property of multi-line text-box controls. Data Limits
Specific data limits for Visual Basic version 3.0 are well documented in Appendix D of the Microsoft Visual Basic "Programmer's Guide." Please look there for information on data limits. Global Name Table
Each application uses a single Global name table (up to 64K in size) that contains all Global names. Global names include the following:
 The actual text of the Form or Code module name.
 The actual text of each event procedure name appears in the Global symbol table only once. For example, two different forms each have a Form_Load event procedure, but only one entry for the event procedure is made in the Global symbol table.
 The actual text of each non-event Sub or Function procedure name in a form module (.FRM file). Even though these Sub or Function procedures are private to the form, within the application, their names are listed globally but with a flag set to indicate that they are private to that   form.
 The actual text of each non-event Sub or Function procedure name in a code module (.BAS file). As with Sub or Function procedure names in a form module, the code module Sub and Function procedure names are listed globally but with a flag set to indicate that they are global to the application (unless the Private key word is used, in which case the flag is set to indicate that they are private to that code module).
 The actual text for the name of each Global constant.
 The actual text for the name of each Global variable.
 The actual text for the name of each user-defined type definition.
 The actual text for the name of each Global DLL Sub or Function procedure declaration.
 Four bytes of overhead for each of the above listed Global names in the Global name table as well as approximately 100 bytes of overhead for the hash table for these Global names.

NOTE: When your project is made into an .EXE file, most of the Global name table is not needed. Visual Basic takes special provisions to ensure that only the names that are needed are included with the .EXE (such as DLL function names). Global Symbol Table
Each application has a single Global symbol table that is up to 64K in size. This table contains descriptive information about each of the items named in the Global name table. Specifically, this table contains:
 Type definitions: 4 bytes for the type plus 4 bytes for each element.
 Type variables: 12 bytes.
 Fixed-string variables: 12 bytes.
 Object variables: 12 bytes (approximately).
 Everything else: 10 bytes (approximately).
 Approximately 100 bytes of overhead for the hash table within the Global symbol table.

NOTE: When your project is made into an .EXE file, the Global symbol table does not exist. It is only needed within the Visual Basic environment to create the .EXE file itself. Global Data Segment
Each Visual Basic application receives a single data segment of up to 64K (minus overhead) to store the actual data referenced by Global variables and Global constants.
Space for Global string constant descriptors is also allocated in this data segment. However, the actual string data for the Global string constant is stored in a segment of up to 32K (minus overhead) allocated separately from dynamic memory.
A custom control (.VBX) is allocated space in the same 32K segment for any strings obtained with the Visual Basic API VBCreateHlstr. If the custom control does not deallocate this space, because it needs to reference these strings when it is unloaded or it doesn't clean up properly, the data in the segment may exceed 32K. If this occurs, Visual Basic allocates another segment to hold the excess data and links this new segment into the dynamic data segment chain. Module Name Table
Each form and code module has a single Module name table that is up to 64K in size. The Module name table includes:
 The actual text for the name of each module-level and local variable name.
 The actual text for the name of each module-level DLL Sub or Function procedure declaration.
 The actual text used for line numbers and line labels.
 As with the Global name table, an additional four-byte overhead for each of the above listed module-level names in the Module name table as well as about 100 bytes  overhead for the hash table for these module-level names.

NOTE: As with the Global name table, when your project is made into an .EXE file, most of the Module name table is not needed. Module Symbol Table
Each form and code module has a single Module symbol table that is up to 64K in size. The module symbol table contains much of the same information as the Global symbol table, except for Type definitions.

NOTE: As with the Module symbol table, when your project is made into an .EXE files most of the Module name table is not needed. Module Data Segment
Each form and code module has its own 64K module data segment. The contents of the module data segment include:
 Local variables declared with the Static keyword.
 Local variables declared within a Static Sub or Function procedure.
 Module-level, fixed-length string variables.
 Module-level variables other than arrays and variable-length strings.
 Module-level constants.
 Tracking data for arrays and variable-length strings (2-byte pointer each).
 Tracking data for controls referenced in code for a form (2-byte pointer each).
 Tracking data for nonstatic local variables (2-byte pointer each). Module Code Segment
Each Sub or Function procedure in a form or code module can contain up to 64K of p-code (the internal representation of your code). The module-level declaration section of each form or code module can also contain up to 64K of p-code. If the procedure-level or module-level p-code exceeds this limit, Visual Basic generates an "Out of Memory" error message. There is no specific internal limit to the total size of an individual form or code module.
The amount of p-code in a procedure or in the Declarations section of a module is roughly equivalent to the number of ASCII text characters in the code. The Visual Basic documentation recommends that you save your forms and modules as ASCII text and that you keep the size of individual procedure-level or module-level code in your form and code modules to under 64K. However, practical experience by Visual Basic programmers has shown that it is best to keep the size of these under 45K to 50K of ASCII text.
This estimate is true only when you are in the development environment. Visual Basic does not include identifiers (procedure, variable, and object names) or comments in the .EXE files you create, so the resulting .EXE is much smaller. If you don't exceed the 64K limit on p-code in the development environment, you won't exceed it in the finished .EXE. System Resources
The data space (heap) attached to the Windows libraries (USER.EXE and GDI.EXE) is the space allocated for system resources. The data space used by the GDI library contains graphics information regarding brushes, fonts, icons, and so on. The data space used by the USER library contains style information pertaining to windows (forms) and controls. The data space for each of these libraries is limited to 64K. The "About Program Manager" menu command displays, as a percentage, the lower of these two areas of memory. If you run out of either of these two heaps you will receive an "Out of Memory" error message.
Visual Basic uses Windows resources shared with other Windows applications, so it is important to make efficient use of these resources to avoid "Out of Memory" messages. For larger applications, you should reduce the number of forms and controls loaded at any one time. Forms should be loaded only when needed. Here are some ways to reduce the number of controls:
 Use the Visual Basic Load and Unload statements to load forms only when needed at run time.
 Use so called lightweight controls (labels, images, lines, and shapes in Visual Basic version 3.0) when possible. These controls are similar to other controls in that they do use system resources when they are being drawn or updated in the screen. But unlike other controls, the lightweight controls release resources back to the system when finished.
 Replace controls such as command buttons that react to mouse events with an image control that has a picture of a control in it. This provides your application with similar functionality but uses less memory (system resources).
 Try to replace several related controls with a single, larger control. For example, if several text boxes were placed on a form to represent the cells of a spreadsheet, you could replace these controls with a single picture control containing an image of the cells: lines drawn vertically and horizontally. Hit testing could be performed at run time
from within the MouseDown event of the picture control. In other words, you could use the x and y coordinates passed to the MouseDown event to determine which "cell" was clicked (hit). The cell image on the picture control could be temporarily replaced by a real text box, positioned by using the Move method to allow for user input. In this manner, only two controls would be required to simulate input on a spreadsheet:
a picture control and a text box. Stack Space
Each Visual Basic application uses a single stack limited to 20K in size. The 20K size cannot be changed, so an "Out of Stack Space" error can easily occur if your program performs uncontrolled recursion, such as a cascading event.
Visual Basic itself uses the stack, even in a .EXE, so the practical limit is lower than 20K. A simple way to get an idea of this to make an .EXE file of a form with a single command button on it with the following code. Each Gosub takes 4 bytes of stack space, so you can then calculate how much free stack space you had when your procedure started.
    Sub Command1_Click ()
      Dim frameCount as Integer
      frameCount = 0
      frameCount = frameCount + 1
      Print frameCount * 4
      GoSub Overflow_Stack
   End Sub

Procedure arguments and local variables in Sub and Function procedures take up stack space at run time. However, Global variables, module-level variables, and procedure-level variables declared with the STATIC keyword, and arguments in Sub or Function procedures that are defined with the STATIC keyword, don't take up stack space because they are allocated in the Module Data Segments of form and code modules.
2.5.6. When Code and Resources Are Loaded or Unloaded
When an application is executed, memory is allocated for the Global Data Segment and the appropriate data is loaded into it. This stays persistent until the application terminates.
When a form is loaded, system resources are allocated for the Form and all controls on that form. In addition, memory is allocated for the Module data segment and the appropriate data is loaded into it.
Each Visual Basic form or module consists of one or more code segments in the .EXE file. The code segments are marked LOADONCALL, MOVEABLE, and DISCARDABLE, which you can verify by using a copy of EXEHDR.EXE to dump the file header information. Thus, on first reference to the form or module, Windows loads the code associated with it. Windows is then free to discard it and demand-load it as it sees fit (for example, if you run low on memory). Unloading a form will not force the code segment out of memory, it's still present until Windows decides to discard the code segment.
Unloading a form does unload the instance of that form and all resources used by it and the controls on that form. However, when a form is unloaded, the Module Data Segment is not unloaded; it remains in memory until the application terminates. Thus, if you load a Form, change the values of some module level variables, unload the Form, and then load it again, the value you last assigned to the module level variable in the Form will still be present. To deallocate memory used by the Module data segment in the form, use the following line of code after you unload the form: (This will clear all data in the Module code segment for the form.)  
Unload Form2
Set Form2 = Nothing


Author Comment

ID: 1436175
Many thanks

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
This article describes how to use a set of graphical playing cards to create a Draw Poker game in Excel or VB6.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

601 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question