PRODUCT   :  R:BASE                  VERSION      :  3.1
   Memory management is a complex, technical subject. Here's a basic
   introduction to how R:BASE lays out and organizes your computer's
   conventional memory.
   Future R:BASE EXCHANGE articles will go into more detail about what
   actually happens in these areas. The purpose of this article is to
   give you the overall picture of the four memory areas and the two
   dynamic memory managers. This lays the groundwork for future articles
   that will show you how to use this knowledge to improve performance.
   R:BASE Memory Areas
   R:BASE has four memory areas--two dynamic and two static.
     o  Dynamic Data Area--holds memory blocks, each with its own memory
        handle. Memory blocks hold pieces of R:BASE commands,
        applications, and databases. If R:BASE says you've run out of
        dynamic memory or buffer space, it's your Dynamic Data Area that
        has run out of room.
     o  Dynamic Code Area--holds virtual memory pages containing pieces
        of R:BASE internal code. Each virtual memory page is a little
        piece of the RBASE.EXE program.
     o  Static Data Area--holds some types of data that go into memory
        and stay put. R:BASE handles this area internally. It always
        occupies 100K of memory.
     o  Static Code Area--holds input and output code that goes into
        memory and stays put. R:BASE handles this area internally. It
        always occupies 200K of memory.
   R:BASE Memory Map
   Here's a picture of how conventional memory might look if your memory
   has no TSRs (terminate and stay resident programs) and uses exactly
   70K for network drivers.
   Dynamic Memory Managers
   The two dynamic memory managers manage the dynamic memory areas.
     o  Dynamic Code Manager--moves pieces of R:BASE internal code (code
        from RBASE.EXE) in and out of the Dynamic Code Area. As it does
        this, it tries to keep the most frequently used code in the
        Dynamic Code Area to make R:BASE faster. The Code Manager comes
        from ".RTLink" from Pocketsoft, Inc.
     o  Dynamic Data Manager--moves R:BASE application programs,
        variables, and database information in and out of the Dynamic
        Data Area.
   How DOS Loads an .EXE
   DOS loads an .EXE program into memory in four steps:
     o  It opens the .EXE file and reads the .EXE header. The header
        gives DOS the memory requirements.
     o  It allocates the amount of memory that the program needs.
     o  It reads the program into memory.
     o  It corrects (fixes) the program's relative memory addresses. A
        relative memory address is a memory location relative to the
        start of the program. Once DOS knows the absolute address of the
        start of the program, it converts (fixes) the relative addresses
        into absolute addresses.
   Loading RBASE.EXE
   When DOS loads RBASE.EXE into memory, it allocates space for the
   static areas, and loads the two dynamic memory managers into the
   static code area.
   Next, R:BASE initializes the Dynamic Code Manager, which allocates
   memory for the Dynamic Code Area.
   Then R:BASE initializes the Dynamic Data Manager, which allocates
   memory for the Dynamic Data Area. Now R:BASE is ready to go to work.
   Static Data & Static Code Areas
   The Static Data Area holds items that because of frequent use must be
   fast, items that can't go in the Dynamic Data Area, and items that are
   a constant size and must always be kept in memory. Here are some
     o  Keyboard buffer
     o  R:BASE settings
     o  The stack--all DOS programs have a stack to control flow and
        store temporary values
     o  Database information such as the database path and name
     o  Virtual Page information table
     o  Memory block information table
   The Static Code Area holds input and output code like this:
     o  Screen output code
     o  Keyboard input code
     o  File input and output code
     o  Database input and output code
     o  Dynamic Code Manager
   Dynamic Code--Virtual Pages
   When DOS finished loading R:BASE it really only loaded a small part of
   the R:BASE code. R:BASE tricks DOS into thinking that it contains 200K
   of code and 100K of data. Actually it contains about 1800K of code.
   MICRORIM ONLINE July 1991 ------------------------------ Page 10 of 34
   The .EXE header was modified to prevent DOS from trying to load the
   whole program and returning an out-of-memory error because it was too
   big to fit in 640K of memory.
   The remaining 1600K of code is broken up into 950 individual pieces,
   called "virtual pages." As the virtual pages are needed, the Dynamic
   Code Manager reads them from the .EXE into the Dynamic Code Area and
   executes them there.
   Each virtual page contains its own code and relative memory reference
   table, so each page is like a separate .EXE. This allows each to be
   moved around in memory. Each time they're moved into memory, the
   Dynamic Code Manager fixes the relative memory references into the
   appropriate new absolute memory references in order to execute that
   code in the new absolute memory location.
   When the code in a virtual page needs to be executed, it's the Dynamic
   Code Manager's job to load that page and execute the desired code.
   When the Dynamic Code Area is full and another page needs to be
   loaded, the Dynamic Code Manager decides which virtual page to discard
   and where to put it.
   The Dynamic Code Manager keeps the most recently and most heavily used
   virtual pages by discarding the least recently used page. It knows
   which one this is because it increments a counter each time a page is
   used, and decrements that counter over time. It discards the pages
   with the smallest counter values.
   The Dynamic Code Manager decides where to put the discarded page.
   First choice is to swap it to expanded memory (EMS version 3.2 or
   higher). Second choice is to swap it to extended memory (XMS version
   2.0 or higher). If it can't do either of these, it discards the page,
   re-reading the page from disk if it's needed again.
   Virtual pages are like little .EXEs. They're movable, swapable, and
   discardable. The location of each virtual page is stored in the Static
   Data Area, so the Dynamic Code Manager can quickly find each one.
   Dynamic Data--Memory Blocks
   After the Dynamic Code Manager allocates memory for the Dynamic Code
   Area, the Dynamic Data Manager allocates memory for the Dynamic Data
   The Dynamic Data Area is made up of memory blocks each with its own
   identifying memory handle. There can be a maximum of 300 memory blocks
   (handles). The Dynamic Data Area has both dynamic memory space (data
   buffer or data space) and up to 300 memory handles (blocks). You need
   to be careful not to run out of either one.
   Here are examples of the dynamic data that R:BASE puts into memory
   blocks in the Dynamic Data Area:
     o  Table and column lists
     o  Database, file, and sort buffers
     o  R:BASE commands and programs
     o  R:BASE global variables
   The memory blocks that make up the Dynamic Data Area can vary in size
   and move around in memory. They can be swapped to disk or even
   discarded. The Dynamic Data Manager knows the following about each
   memory block in the Dynamic Data Area:
     o  Its size
     o  Its location in memory or on disk
     o  If it's in use
     o  Whether it can be swapped to disk
     o  If it can be discarded
   A database buffer is an example of a memory block that can be
   discarded when it isn't being used. This is because the data in a
   database buffer is just a copy of the data in the database. It's
   faster to just throw it away and re-read it from the database than to
   swap it to disk and re-read it from the swap file.
   When R:BASE needs a new memory block, the Dynamic Data Manager must
   decide where in the Dynamic Data Area to put the new block. First, it
   looks for unused memory; if it finds enough, it's done. If it doesn't,
   R:BASE looks for an existing memory block that can be swapped or
   discarded. If it can't find a single block that will provide enough
   space, it swaps or discards all the blocks. If there still isn't
   enough free memory, R:BASE gives an out-of-memory error.
   A smaller Dynamic Data Area leaves more room for the Dynamic Code
   Area, so R:BASE won't have to swap the virtual pages as much. But the
   Dynamic Data Area must be large enough to run your application without
   running out of memory space.
   The Dynamic Memory Area Sizes
   The dynamic areas vary in size depending on the amount of free memory
   available after loading the static areas, and the value of a DOS
   environment variable (RTVMCONV), which you can set before you start
   R:BASE. A future article will explain how to set RTVMCONV and how to
   use the ISTAT function to check memory.
   The size of the Dynamic Data Area limits the complexity of
   applications, the maximum size of the database schema, and the
   performance of complex applications.
   The size of the Dynamic Code Area impacts the performance of R:BASE in
   general and limits the number of R:BASE features that can be used
   together, and still run quickly.
   Tips for Better Performance
   Here are some performance enhancement tips:
     o  Design your code in small chunks so your application will do an
        operation only if the user asks for it.
     o  Avoid comments, long table names, and long column names. They use
        up space in the Dynamic Data Area.
     o  Make your EEPs (Entry/Exit Procedures) in forms small. A large
        EEP may cause the Dynamic Code Manager to discard the FORMS
        internal R:BASE code, which must then be reloaded when the EEP
     o  Group commands together so R:BASE can keep a particular virtual
        page in memory. For example, put all the SET VAR commands
        together, all the SELECT commands together, and all the UPDATE
        commands together. If you do this, the Dynamic Code Manager won't
        have to swap the virtual pages that run those commands in and out
        of the Dynamic Code Area. Less swapping and discarding can make
        an application faster.
     o  Make the Browse/Edit menu run faster by setting LAYOUT OFF when
        you don't need to save the layout.
     o  Speed up the R:BASE Main Menu by getting rid of forms and reports
        you don't need.
   Fewer Out-of-memory Errors
   When you run out of memory, you have either run out of space in the
   Dynamic Data Area, or you have attempted to exceed the maximum number
   of memory handles available in the Dynamic Data Area. R:BASE 3.1A
   gives you two separate messages so you can know which one you ran out
   of (handles or dynamic space). Earlier R:BASE versions say only that
   you have run out of dynamic space when in fact you may have plenty of
   space but no more memory handles.
   Try the following methods to get fewer out-of-memory errors:
     o  Use less functionality at a single moment in time.
     o  Remove long names and comments. They take up space.
     o  Lookups in forms and reports don't take up a lot of space, but
        they do use a lot of memory handles.
     o  Reduce the number of saved lookups in forms by setting LOOKUP to
        a lower number. Each saved lookup in a form uses space in the
        Dynamic Data Area. By reducing the number, you can reduce a
        form's memory requirements. The LOOKUP setting tells R:BASE how
        many form lookups to save in memory. Saving lookups in memory
        enables R:BASE to display data more quickly in a form, but each
        saved lookups uses 500 bytes of memory.
     o  Don't use as many rules per table. Rules don't use a lot of
        space, but they do use up memory handles. For example, you might
        exceed the 300 memory handle limit by defining 50 rules on a
        single table.
     o  Reduce the number of columns in a single table. Large tables that
        have more than 100 columns can eat up the space in your Dynamic
        Data Area. Each table access uses 98 bytes per column of the
        Dynamic Data Area.
   By keeping tables small and related to other tables, you'll naturally
   have fewer rules on a single table. That's why a good relational
   design with several related tables--each with only a few columns--is a
   much better use of memory. Better use of memory can pay off in better