Difference between revisions of "Memory Management"

From Suhrid.net Wiki
Jump to navigationJump to search
Line 107: Line 107:
  
 
* Now what if a SO enters ScopedA, then ScopedB and re-enters ScopedA. Now when SO is in innermost ScopedA (top of stack), reference can be made to an object in Scoped B. Now when the Top of stack ScopedA exits, its memory is not reclaimed because the current SO is still active in ScopedA at bottom of stack. When ScopedB exits, its memory is reclaimed and ScopedA is left with a dangling reference.
 
* Now what if a SO enters ScopedA, then ScopedB and re-enters ScopedA. Now when SO is in innermost ScopedA (top of stack), reference can be made to an object in Scoped B. Now when the Top of stack ScopedA exits, its memory is not reclaimed because the current SO is still active in ScopedA at bottom of stack. When ScopedB exits, its memory is reclaimed and ScopedA is left with a dangling reference.
* To avoid this problem, the RTSJ requires that each '''scoped memory area''' (note: only scoped memory area) requires a single parent.
+
* To avoid this problem, the RTSJ requires that each '''scoped memory area''' (note: only scoped memory area) can only have a single parent.
 +
 
  
 
[[Category:RealTimeJava]]
 
[[Category:RealTimeJava]]

Revision as of 09:39, 20 December 2011

Intro

  • Many real time systems have constraints on amount of memory available. e.g. because of cost or size constraints.
  • It is necessary to control how this memory is allocated so that it can be used effectively. By doing this the program can increase its performance and predictability.
  • Assuming a time critical thread is using heap memory, Running garbage collection can have an impact on its response time. (Since the GC Thread cannot be preempted by the RT Thread)
  • Therefore, tt is necessary to provide memory that is not subject to GC.
  • The RTSJ provides two alternatives to traditional Java heap memory:
    • Immortal Memory
    • Scoped Memory
  • Immortal and Scoped memory areas exist outside the heap and are NOT subject to GC.
  • Both types of area are represented by the abstract javax.realtime.MemoryArea class.
  • Only javax.realtime.Schedulable objects are allowed to enter into a MemoryArea. If standard Java threads attempt to get in then an IllegalThreadStateException is thrown.
  • Schedulable objects must explicitly indicate the MemoryArea to allocate objects from, otherwise the standard Java heap will be used.
  • When a memory area is entered by a SO, all object allocation is performed from within that memory area.

Heap Memory

  • Standard Java Heap. Realtime Threads are allowed to use heap memory. Of course, reclamation of this memory is subject to when the JVM runs GC.

Immortal Memory

  • The memory associated with objects allocated in immortal memory is never GC'ed and never released during the lifetime of the application.
  • Immortal memory is shared among all threads.
  • The programmer can reuse the memory by other means. e.g. by maintaining a pool of reusable objects.
  • Class objects and their associated static memories, along with objects created by static initialisation and interned strings (the list of program-defined constant strings that is maintained by the String class) are ALWAYS allocated in immortal memory. This is important, so if an object's static reference is assigned to an object created on scoped memory it will fail, because immortal to scope assignment is not allowed !
  • There is only one instance of ImmortalMemory - it is a singleton object.

Scoped Memory

  • Scoped memory is a memory area where objects with a well-defined lifetime can be allocated.
  • Two types:
    • LTMemory : the allocation time for objects is directly proportional to the size of the object being allocated ,
    • VTMemory : allocation can occur in a variable time.
  • The expectation is that allocation time for objects in VTMemory will be faster but less predictable than allocation in LTMemory.
  • Each scoped memory object has a reference count which indicates the number of times the scope has been entered. Note it doesnt refer to the normal idea of Java GC reference counting.
  • When that reference count goes from 1 to 0, the memory allocated in the scoped memory area can be reclaimed (after running any finalization code associated with the allocated objects).
  • The reference count of a scoped memory area is the count of the number of active calls (explicit or implicit) to its enter method. It is NOT a count of the number of objects that have references to the objects allocated in the scoped memory.

MemoryParameters

  • Can be supplied when creating SO's. They can specify the max amount of memory a SO can consume in the memory area, the maximum immortal area and the rate of allocation.
  • When a SO exceeds its allocation or allocation rate limit, the error is handled as if the allocation failed because of insufficient memory.

MemoryArea Enter

  • The MemoryArea class has a enter() method.
  • Calling the enter() method on a MemoryArea object, will associate the memory area with the current schedulable object for the duration of the execution of the run() method of the instance of Runnable given in the constructor of the MemoryArea or passed as a parameter to the enter method.
  • In the below example, firstMemArea.enter(task) will associate firstMemArea to MyRTThread object for the duration of the RTTask's run() method - so all the objects allocated in the run() method are being allocated from firstMemArea.
  • Note: however the RTTask object is allocated in the heap, because that was the active memory when new RTTask() was being run.
import javax.realtime.*;

public class MAEnter1 {
	
	private class RTTask implements Runnable {
		public void run() {
				System.out.println("Executing in " + RealtimeThread.getCurrentMemoryArea());
				for(int i=1; i <=100; i++) {
					Object obj = new Object();
					System.out.println("Created object " + i);
				}
		}
	}
	
	private final RTTask task = new RTTask();
	
	private final ScopedMemory firstMemArea = new VTMemory(1000000);
	private final ScopedMemory secondMemArea = new VTMemory(1000000);
	
	private class MyRTThread extends RealtimeThread {
		public void run() {
			firstMemArea.enter(task);
			secondMemArea.enter(task);
		}
	}

	public static void main(String[] args) {
		MAEnter1 mpt = new MAEnter1();
		mpt.go();
	}
	
	private void go() {
		MyRTThread rtThread = new MyRTThread();
		rtThread.start();
	}

}

Memory Assignment Rules

  • Different memory areas have differed collection mechansims, so there has to be some restrictions on assignments in different types of memory.
  • For e.g. A reference from ImmortalMemory cannot point to an object created in scope memory, because the memory in the scope area can be reclaimed anytime.
  • Once the object in scope memory is gone, the reference in the ImmortalMemory is a dangling reference.
  • Therefore no asssignments can be made from immortal or heap memory areas to objects created in scoped memory areas.
  • For scope memory areas themselves, assignments to outer scope area is OK - because the outer scope is guaranteed to be active longer than the current scope. Following a similar logic, assignments to inner scopes are forbidden.
  • If a program violates these rules a run time IllegalAssignmentError is thrown.
  • The memory assignment checks are performed at run time because one of the requirements for the RTSJ is that any compiler should be able to compile the code.
  • To keep track of the memory areas used by a SO, the RTJVM uses a stack.
  • From the above rules, it is OK to make assignments to memory areas higher up the stack (the inner scope) but not OK to make assignments to areas lower the stack (the outer scope).
  • The stack can therefore be used to check for violation of memory assignment rules.
  • Now what if a SO enters ScopedA, then ScopedB and re-enters ScopedA. Now when SO is in innermost ScopedA (top of stack), reference can be made to an object in Scoped B. Now when the Top of stack ScopedA exits, its memory is not reclaimed because the current SO is still active in ScopedA at bottom of stack. When ScopedB exits, its memory is reclaimed and ScopedA is left with a dangling reference.
  • To avoid this problem, the RTSJ requires that each scoped memory area (note: only scoped memory area) can only have a single parent.