- Memory Management
- Asynchronous Event Handling
- Asynchronous Transfer of Control
- Asynchronous Thread Termination
- Physical Memory Access
- Minimum Implementations of the RTSJ
- Optionally Required Components
- Documentation Requirements
- Parameter Objects
- Java Platform Dependencies
Garbage-collected memory heaps have always been considered an obstacle to real-time programming due to the unpredictable latencies introduced by the garbage collector. The RTSJ addresses this issue by providing several extensions to the memory model, which support memory management in a manner that does not interfere with the ability of real-time code to provide deterministic behavior. This goal is accomplished by allowing the allocation of objects outside of the garbage-collected heap for both short-lived and long-lived objects.
The RTSJ introduces the concept of a memory area. A memory area represents an area of memory that may be used for the allocation of objects. Some memory areas exist outside of the heap and place restrictions on what the system and garbage collector may do with objects allocated within. Objects in some memory areas are never garbage collected; however, the garbage collector must be capable of scanning these memory areas for references to any object within the heap to preserve the integrity of the heap.
There are four basic types of memory areas:
Scoped memory provides a mechanism for dealing with a class of objects that have a lifetime defined by syntactic scope (cf., the lifetime of objects on the heap).
Physical memory allows objects to be created within specific physical memory regions that have particular important characteristics, such as memory that has substantially faster access.
Immortal memory represents an area of memory containing objects that, once allocated, exist until the end of the application, i.e., the objects are immortal.
Heap memory represents an area of memory that is the heap. The RTSJ does not change the determinant of lifetime of objects on the heap. The lifetime is still determined by visibility.
The RTSJ introduces the concept of scoped memory. A memory scope is used to give bounds to the lifetime of any objects allocated within it. When a scope is entered, every use of new causes the memory to be allocated from the active memory scope. A scope may be entered explicitly, or it can be attached to a RealtimeThread which will effectively enter the scope before it executes the thread's run() method.
Every scoped memory area effectively maintains a count of the number of external references to that memory area. The reference count for a ScopedMemory area is increased by entering a new scope through the enter() method of MemoryArea, by the creation of a RealtimeThread using the particular ScopedMemory area, or by the opening of an inner scope. The reference count for a ScopedMemory area is decreased when returning from the enter() method, when the RealtimeThread using the ScopedMemory exits, or when an inner scope returns from its enter() method. When the count drops to zero, the finalize method for each object in the memory is executed to completion. The scope cannot be reused until finalization is complete and the RTSJ requires that the finalizers execute to completion before the next use (calling enter() or in a constructor) of the scoped memory area.
Scopes may be nested. When a nested scope is entered, all subsequent allocations are taken from the memory associated with the new scope. When the nested scope is exited, the previous scope is restored and subsequent allocations are again taken from that scope.
Because of the unusual lifetimes of scoped objects, it is necessary to limit the references to scoped objects, by means of a restricted set of assignment rules. A reference to a scoped object cannot be assigned to a variable from an enclosing scope, or to a field of an object in either the heap or the immortal area. A reference to a scoped object may only be assigned into the same scope or into an inner scope. The virtual machine must detect illegal assignment attempts and must throw an appropriate exception when they occur.
The flexibility provided in choice of scoped memory types allows the application to use a memory area that has characteristics that are appropriate to a particular syntactically defined region of the code.
ImmortalMemory is a memory resource shared among all threads in an application. Objects allocated in ImmortalMemory are freed only when the Java runtime environment terminates, and are never subject to garbage collection or movement.
The RTSJ also provides limited support for providing memory allocation budgets for threads using memory areas. Maximum memory area consumption and maximum allocation rates for individual real-time threads may be specified when the thread is created.