What are possible solutions to common shared memory issues?
Note: Applies to RTI Data Distribution Service 4.x and above.
First, we need some background to understand how RTI's shared-memory transport works. The RTI Data Distribution Service shared-memory transport uses different standards to access shared mutexes and shared-memory segments, depending on the OS:
- For UNIX-based systems (Linux, Solaris, Mac OS..): SystemV interface
- For Windows systems: Native API interface of Windows
- For QNX, LynxOS, and INTEGRITY systems: POSIX
Every created DataReader has an associated shared segment; this is where the DataReader will receive incoming data. When a DataReader is created, it will first try to find any previously created segments with the same properties. If any segment is found, the segment is reused; otherwise, a new segment is created.
A DataWriter, on the other hand, does not create any segments, but simply attaches to an existing shared-memory segment previously created by a DataReader.
That being said, when a DataWriter shuts down, it simply detaches from the segment. When a DataReader shuts down, it does not destroy the segment either; instead it simply detaches from it (because other DataWriters might still be attached). As a consequence, on a Windows system, there will be no problem at all since the OS will clean everything up. On UNIX and other systems, you might have to clean up the shared-memory segments between runs.
You might then see several common shared-memory issues:
If the issue is related to an unclean shutdown of applications which use shared memory, clean up all unused shared memory segments and semaphores before starting your DDS application.
To see a list of allocated shared-memory objects, enter:
ipcs -a
(the-a
argument shows you the number of processes attached to a segment).To clean up a shared-memory object on a Linux system, use the
ipcrm
command. If you are unfamiliar with the above commands, see their man pages for more information. We recommend cleaning up all the segments that do not have an attached process.- If you are dealing with very large data-types and a high publishing rate, make sure you have enough shared memory available in your system. To check the system settings, enter:
/sbin/sysctl -a | grep shm
The recommended values for a Linux system (it will always depend on your own scenario though) would be:
kernel.shmmni = 4096 kernel.shmall = 268435456 kernel.shmmax = 4294967295
To see the current settings from the /proc filesystem, enter these commands:cat /proc/sys/kernel/shmmni cat /proc/sys/kernel/shmall cat /proc/sys/kernel/shmmax
To increase the shared memory values, you need to modify the file /etc/sysctl.conf. Add the above kernel settings (if they are not already present) with the desired values. Then reload the new values with this command (you will need to be super-user to do this):
sysctl -p
- If the problem is really related to a conflict with another application, the solution is to modify the shared memory keys used by DDS. An application could be using a shared-memory segment with the same key used by a DDS DataReader. In this case, DDS successfully attaches to the segment but it detects an incompatible segment. Then DDS will try to delete the segment and recreate it. But since another application is locking the segment, the delete operation is deferred by the system, so there is no failure reported to DDS. Because of this, the DDS transport could enter an infinite loop where it attaches to a segment, sees the segment is incompatible, then tries to delete it but is deferred.
Comments
ttikkanen
Tue, 10/09/2018 - 02:30
Permalink
Finding correct segments
How do I find relevant segments to be used with
ipcrm
? I want to clean all related to DDS.