Creation and use of shared memory

Shared memory is a common area of storage that is used by all Service Manager server processes on a host machine. Using shared memory is an efficient means of sharing data between processes. For example, when a user or background process first executes a RAD application, Service Manager loads the application into shared memory. This allows other user processes to execute the same application without the overhead of storing a copy of their own into memory. Subsequent executions of the RAD application will result in Service Manager retrieving the application from shared memory thus decreasing the IO required by each process. This behavior of sharing certain data, such as applications, table definitions, and forms between all users significantly increases program performance because reading data from memory is more efficient than reading from disk memory. The total amount of memory used is additionally decreased because one copy of the application, dbdict or form is shared between all users.

The first process that initiates during the startup of Service Manager on the host machine creates the shared memory block in the size defined by the shared_memory parameter in the sm.ini file. The syntax of this parameter is:

shared_memory:<value>

Where <value> is the amount of memory in bytes Service Manager should allocate. This shared memory will be held in the machines virtual memory and thus should not be larger than the virtual memory the machine has available. Information about this allocation can be seen in the sm.log file by locating the line that reads “Creating Resources for system xxxxx with key 0xyyyyyyyyy” (where xxxxx represents the port number you are using and 0xyyyyyyyyy is a system key identifying the shared memory). Every process that connects afterwards attaches to the shared memory that was created by the first process. Information about this attachment can be seen in the sm.log file by locating the line that reads “Attaching to resources for system xxxxx with key 0xyyyyyyyyy.”. However, execution of some reports, like sm –reportsem, sm -reportshm and sm –reportlic, will not create shared memory because they are designed to only read data from existing shared memory.

Example: Shared Memory involvement during the login process

The login application is called. Service Manager will check shared memory, find that the login application is not currently stored there, retrieves the code record for the application from the database, and then loads it into shared memory. At this point, Service Manager will begin to execute the login application. Once it determines that the login.prompt form needs to be displayed, it will check shared memory for the form, find that it is not currently stored there, retrieve the login.prompt form from the database and load it into shared memory. Once the form is displayed, the user enters their userid and password, the application then attempts to validate this information against Service Manager’s operator file. This method of checking shared memory, retrieving the item from the database, and storing it into shared memory continues throughout the life of the process. For this reason, the first user to log into Service Manager is responsible for loading most of the contents of shared memory, which allows each subsequent user to benefit.

Shared Memory Management

Because the memory in the allocated shared memory area is not released until the Service Manager server processes are stopped, the initial overhead of allocating does not depend on users logging in and out of Service Manager. It is assumed that while the server is operating, users will be logging in and out routinely and they will require continuous access to shared memory. Depending on the information, memory is released for reuse within the shared memory area at different times. For example, User Blocks are freed when the user logs out, and cached items are released when they are no longer needed. Cached information that has changed is flagged obsolete and a copy of the changed record is loaded into shared memory with the first user requesting the record after the change. The obsolete record is freed when the use count of the record is at 0, meaning all user processes using this record have released it from use.

For example, when a RAD application has changed, the old version is flagged obsolete if it is still in use and the new version is loaded into shared memory by the next user requesting the RAD application. This occurs because the system cannot find a current copy of the record in shared memory at that time. The obsolete record is freed when the last user still using the old code record releases it. If the IR area of shared memory reaches its size limit (default is 30 % of total allocated shared memory), the least recently used record is removed from memory to allow for new records to be loaded.

Shared memory in Service Manager is divided into various size blocks of storage. The sizes available (in bytes) are 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, and BIG_ALLOC. Any request for shared storage greater than 8192 bytes is satisfied from the BIG_ALLOC pool. Smaller sized blocks are not allocated one at a time, but instead, come from a pool of similar sized requests. For example, when a request is made for 16 bytes of shared storage and there is no 16 byte block free, Service Manager will allocate a 32K byte block from the lower end of shared memory and divide that 32K area into 16 byte blocks. The first 16 byte block would be returned to the requestor and the remaining 16 byte blocks would remain on the 16 byte block free chain for later allocation. BIG ALLOC starts at the end of the allocated shared memory. When both ends (<8K and BIG ALLOC) meet, Service Manager is out of shared memory.